|
|
@ -539,7 +539,7 @@ static void get_tag(AVFormatContext *s, AVIOContext *pb, const char *key, int ty |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
av_freep(&buf); |
|
|
|
av_freep(&buf); |
|
|
|
av_log(s, AV_LOG_WARNING, "unsupported metadata entry; key:%s, type:%d, length:0x%x\n", key, type, length); |
|
|
|
av_log(s, AV_LOG_WARNING, "unsupported metadata entry; key:%s, type:%d, length:0x%x\n", key, type, length); |
|
|
|
url_fskip(pb, length); |
|
|
|
avio_seek(pb, length, SEEK_CUR); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -582,7 +582,7 @@ static int parse_videoinfoheader2(AVFormatContext *s, AVStream *st) |
|
|
|
WtvContext *wtv = s->priv_data; |
|
|
|
WtvContext *wtv = s->priv_data; |
|
|
|
AVIOContext *pb = wtv->pb; |
|
|
|
AVIOContext *pb = wtv->pb; |
|
|
|
|
|
|
|
|
|
|
|
url_fskip(pb, 72); // picture aspect ratio is unreliable
|
|
|
|
avio_seek(pb, 72, SEEK_CUR); // picture aspect ratio is unreliable
|
|
|
|
ff_get_bmp_header(pb, st); |
|
|
|
ff_get_bmp_header(pb, st); |
|
|
|
|
|
|
|
|
|
|
|
return 72 + 40; |
|
|
|
return 72 + 40; |
|
|
@ -658,17 +658,17 @@ static AVStream * parse_media_type(AVFormatContext *s, AVStream *st, int sid, |
|
|
|
|
|
|
|
|
|
|
|
if (size < 32) { |
|
|
|
if (size < 32) { |
|
|
|
av_log(s, AV_LOG_WARNING, "format buffer size underflow\n"); |
|
|
|
av_log(s, AV_LOG_WARNING, "format buffer size underflow\n"); |
|
|
|
url_fskip(pb, size); |
|
|
|
avio_seek(pb, size, SEEK_CUR); |
|
|
|
return NULL; |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
url_fskip(pb, size - 32); |
|
|
|
avio_seek(pb, size - 32, SEEK_CUR); |
|
|
|
ff_get_guid(pb, &actual_subtype); |
|
|
|
ff_get_guid(pb, &actual_subtype); |
|
|
|
ff_get_guid(pb, &actual_formattype); |
|
|
|
ff_get_guid(pb, &actual_formattype); |
|
|
|
avio_seek(pb, -size, SEEK_CUR); |
|
|
|
avio_seek(pb, -size, SEEK_CUR); |
|
|
|
|
|
|
|
|
|
|
|
st = parse_media_type(s, st, sid, mediatype, actual_subtype, actual_formattype, size - 32); |
|
|
|
st = parse_media_type(s, st, sid, mediatype, actual_subtype, actual_formattype, size - 32); |
|
|
|
url_fskip(pb, 32); |
|
|
|
avio_seek(pb, 32, SEEK_CUR); |
|
|
|
return st; |
|
|
|
return st; |
|
|
|
} else if (!ff_guidcmp(mediatype, mediatype_audio)) { |
|
|
|
} else if (!ff_guidcmp(mediatype, mediatype_audio)) { |
|
|
|
st = new_stream(s, st, sid, AVMEDIA_TYPE_AUDIO); |
|
|
|
st = new_stream(s, st, sid, AVMEDIA_TYPE_AUDIO); |
|
|
@ -679,7 +679,7 @@ static AVStream * parse_media_type(AVFormatContext *s, AVStream *st, int sid, |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
if (ff_guidcmp(formattype, format_none)) |
|
|
|
if (ff_guidcmp(formattype, format_none)) |
|
|
|
av_log(s, AV_LOG_WARNING, "unknown formattype:"PRI_GUID"\n", ARG_GUID(formattype)); |
|
|
|
av_log(s, AV_LOG_WARNING, "unknown formattype:"PRI_GUID"\n", ARG_GUID(formattype)); |
|
|
|
url_fskip(pb, size); |
|
|
|
avio_seek(pb, size, SEEK_CUR); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (!memcmp(subtype + 4, (const uint8_t[]){MEDIASUBTYPE_BASE_GUID}, 12)) { |
|
|
|
if (!memcmp(subtype + 4, (const uint8_t[]){MEDIASUBTYPE_BASE_GUID}, 12)) { |
|
|
@ -701,14 +701,14 @@ static AVStream * parse_media_type(AVFormatContext *s, AVStream *st, int sid, |
|
|
|
return NULL; |
|
|
|
return NULL; |
|
|
|
if (!ff_guidcmp(formattype, format_videoinfo2)) { |
|
|
|
if (!ff_guidcmp(formattype, format_videoinfo2)) { |
|
|
|
int consumed = parse_videoinfoheader2(s, st); |
|
|
|
int consumed = parse_videoinfoheader2(s, st); |
|
|
|
url_fskip(pb, FFMAX(size - consumed, 0)); |
|
|
|
avio_seek(pb, FFMAX(size - consumed, 0), SEEK_CUR); |
|
|
|
} else if (!ff_guidcmp(formattype, format_mpeg2_video)) { |
|
|
|
} else if (!ff_guidcmp(formattype, format_mpeg2_video)) { |
|
|
|
int consumed = parse_videoinfoheader2(s, st); |
|
|
|
int consumed = parse_videoinfoheader2(s, st); |
|
|
|
url_fskip(pb, FFMAX(size - consumed, 0)); |
|
|
|
avio_seek(pb, FFMAX(size - consumed, 0), SEEK_CUR); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
if (ff_guidcmp(formattype, format_none)) |
|
|
|
if (ff_guidcmp(formattype, format_none)) |
|
|
|
av_log(s, AV_LOG_WARNING, "unknown formattype:"PRI_GUID"\n", ARG_GUID(formattype)); |
|
|
|
av_log(s, AV_LOG_WARNING, "unknown formattype:"PRI_GUID"\n", ARG_GUID(formattype)); |
|
|
|
url_fskip(pb, size); |
|
|
|
avio_seek(pb, size, SEEK_CUR); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (!memcmp(subtype + 4, (const uint8_t[]){MEDIASUBTYPE_BASE_GUID}, 12)) { |
|
|
|
if (!memcmp(subtype + 4, (const uint8_t[]){MEDIASUBTYPE_BASE_GUID}, 12)) { |
|
|
@ -726,7 +726,7 @@ static AVStream * parse_media_type(AVFormatContext *s, AVStream *st, int sid, |
|
|
|
return NULL; |
|
|
|
return NULL; |
|
|
|
if (ff_guidcmp(formattype, format_none)) |
|
|
|
if (ff_guidcmp(formattype, format_none)) |
|
|
|
av_log(s, AV_LOG_WARNING, "unknown formattype:"PRI_GUID"\n", ARG_GUID(formattype)); |
|
|
|
av_log(s, AV_LOG_WARNING, "unknown formattype:"PRI_GUID"\n", ARG_GUID(formattype)); |
|
|
|
url_fskip(pb, size); |
|
|
|
avio_seek(pb, size, SEEK_CUR); |
|
|
|
st->codec->codec_id = CODEC_ID_DVB_SUBTITLE; |
|
|
|
st->codec->codec_id = CODEC_ID_DVB_SUBTITLE; |
|
|
|
return st; |
|
|
|
return st; |
|
|
|
} else if (!ff_guidcmp(mediatype, mediatype_mstvcaption) && |
|
|
|
} else if (!ff_guidcmp(mediatype, mediatype_mstvcaption) && |
|
|
@ -736,21 +736,21 @@ static AVStream * parse_media_type(AVFormatContext *s, AVStream *st, int sid, |
|
|
|
return NULL; |
|
|
|
return NULL; |
|
|
|
if (ff_guidcmp(formattype, format_none)) |
|
|
|
if (ff_guidcmp(formattype, format_none)) |
|
|
|
av_log(s, AV_LOG_WARNING, "unknown formattype:"PRI_GUID"\n", ARG_GUID(formattype)); |
|
|
|
av_log(s, AV_LOG_WARNING, "unknown formattype:"PRI_GUID"\n", ARG_GUID(formattype)); |
|
|
|
url_fskip(pb, size); |
|
|
|
avio_seek(pb, size, SEEK_CUR); |
|
|
|
st->codec->codec_id = CODEC_ID_DVB_TELETEXT; |
|
|
|
st->codec->codec_id = CODEC_ID_DVB_TELETEXT; |
|
|
|
return st; |
|
|
|
return st; |
|
|
|
} else if (!ff_guidcmp(mediatype, mediatype_mpeg2_sections) && |
|
|
|
} else if (!ff_guidcmp(mediatype, mediatype_mpeg2_sections) && |
|
|
|
!ff_guidcmp(subtype, mediasubtype_mpeg2_sections)) { |
|
|
|
!ff_guidcmp(subtype, mediasubtype_mpeg2_sections)) { |
|
|
|
if (ff_guidcmp(formattype, format_none)) |
|
|
|
if (ff_guidcmp(formattype, format_none)) |
|
|
|
av_log(s, AV_LOG_WARNING, "unknown formattype:"PRI_GUID"\n", ARG_GUID(formattype)); |
|
|
|
av_log(s, AV_LOG_WARNING, "unknown formattype:"PRI_GUID"\n", ARG_GUID(formattype)); |
|
|
|
url_fskip(pb, size); |
|
|
|
avio_seek(pb, size, SEEK_CUR); |
|
|
|
return NULL; |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
av_log(s, AV_LOG_WARNING, "unknown media type, mediatype:"PRI_GUID |
|
|
|
av_log(s, AV_LOG_WARNING, "unknown media type, mediatype:"PRI_GUID |
|
|
|
", subtype:"PRI_GUID", formattype:"PRI_GUID"\n", |
|
|
|
", subtype:"PRI_GUID", formattype:"PRI_GUID"\n", |
|
|
|
ARG_GUID(mediatype), ARG_GUID(subtype), ARG_GUID(formattype)); |
|
|
|
ARG_GUID(mediatype), ARG_GUID(subtype), ARG_GUID(formattype)); |
|
|
|
url_fskip(pb, size); |
|
|
|
avio_seek(pb, size, SEEK_CUR); |
|
|
|
return NULL; |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -779,17 +779,17 @@ static int parse_chunks(AVFormatContext *s, int mode, int64_t seekts, int *len_p |
|
|
|
if (len < 32) |
|
|
|
if (len < 32) |
|
|
|
break; |
|
|
|
break; |
|
|
|
sid = avio_rl32(pb) & 0x7FFF; |
|
|
|
sid = avio_rl32(pb) & 0x7FFF; |
|
|
|
url_fskip(pb, 8); |
|
|
|
avio_seek(pb, 8, SEEK_CUR); |
|
|
|
consumed = 32; |
|
|
|
consumed = 32; |
|
|
|
|
|
|
|
|
|
|
|
if (!ff_guidcmp(g, stream_guid)) { |
|
|
|
if (!ff_guidcmp(g, stream_guid)) { |
|
|
|
if (ff_find_stream_index(s, sid) < 0) { |
|
|
|
if (ff_find_stream_index(s, sid) < 0) { |
|
|
|
ff_asf_guid mediatype, subtype, formattype; |
|
|
|
ff_asf_guid mediatype, subtype, formattype; |
|
|
|
int size; |
|
|
|
int size; |
|
|
|
url_fskip(pb, 28); |
|
|
|
avio_seek(pb, 28, SEEK_CUR); |
|
|
|
ff_get_guid(pb, &mediatype); |
|
|
|
ff_get_guid(pb, &mediatype); |
|
|
|
ff_get_guid(pb, &subtype); |
|
|
|
ff_get_guid(pb, &subtype); |
|
|
|
url_fskip(pb, 12); |
|
|
|
avio_seek(pb, 12, SEEK_CUR); |
|
|
|
ff_get_guid(pb, &formattype); |
|
|
|
ff_get_guid(pb, &formattype); |
|
|
|
size = avio_rl32(pb); |
|
|
|
size = avio_rl32(pb); |
|
|
|
parse_media_type(s, 0, sid, mediatype, subtype, formattype, size); |
|
|
|
parse_media_type(s, 0, sid, mediatype, subtype, formattype, size); |
|
|
@ -800,10 +800,10 @@ static int parse_chunks(AVFormatContext *s, int mode, int64_t seekts, int *len_p |
|
|
|
if (stream_index >= 0 && !((WtvStream*)s->streams[stream_index]->priv_data)->seen_data) { |
|
|
|
if (stream_index >= 0 && !((WtvStream*)s->streams[stream_index]->priv_data)->seen_data) { |
|
|
|
ff_asf_guid mediatype, subtype, formattype; |
|
|
|
ff_asf_guid mediatype, subtype, formattype; |
|
|
|
int size; |
|
|
|
int size; |
|
|
|
url_fskip(pb, 12); |
|
|
|
avio_seek(pb, 12, SEEK_CUR); |
|
|
|
ff_get_guid(pb, &mediatype); |
|
|
|
ff_get_guid(pb, &mediatype); |
|
|
|
ff_get_guid(pb, &subtype); |
|
|
|
ff_get_guid(pb, &subtype); |
|
|
|
url_fskip(pb, 12); |
|
|
|
avio_seek(pb, 12, SEEK_CUR); |
|
|
|
ff_get_guid(pb, &formattype); |
|
|
|
ff_get_guid(pb, &formattype); |
|
|
|
size = avio_rl32(pb); |
|
|
|
size = avio_rl32(pb); |
|
|
|
parse_media_type(s, s->streams[stream_index], sid, mediatype, subtype, formattype, size); |
|
|
|
parse_media_type(s, s->streams[stream_index], sid, mediatype, subtype, formattype, size); |
|
|
@ -822,11 +822,11 @@ static int parse_chunks(AVFormatContext *s, int mode, int64_t seekts, int *len_p |
|
|
|
const uint8_t *pbuf = buf; |
|
|
|
const uint8_t *pbuf = buf; |
|
|
|
int buf_size; |
|
|
|
int buf_size; |
|
|
|
|
|
|
|
|
|
|
|
url_fskip(pb, 8); |
|
|
|
avio_seek(pb, 8, SEEK_CUR); |
|
|
|
consumed += 8; |
|
|
|
consumed += 8; |
|
|
|
if (!ff_guidcmp(g, EVENTID_CtxADescriptorSpanningEvent) || |
|
|
|
if (!ff_guidcmp(g, EVENTID_CtxADescriptorSpanningEvent) || |
|
|
|
!ff_guidcmp(g, EVENTID_CSDescriptorSpanningEvent)) { |
|
|
|
!ff_guidcmp(g, EVENTID_CSDescriptorSpanningEvent)) { |
|
|
|
url_fskip(pb, 6); |
|
|
|
avio_seek(pb, 6, SEEK_CUR); |
|
|
|
consumed += 6; |
|
|
|
consumed += 6; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -840,7 +840,7 @@ static int parse_chunks(AVFormatContext *s, int mode, int64_t seekts, int *len_p |
|
|
|
if (stream_index >= 0) { |
|
|
|
if (stream_index >= 0) { |
|
|
|
AVStream *st = s->streams[stream_index]; |
|
|
|
AVStream *st = s->streams[stream_index]; |
|
|
|
int audio_type; |
|
|
|
int audio_type; |
|
|
|
url_fskip(pb, 8); |
|
|
|
avio_seek(pb, 8, SEEK_CUR); |
|
|
|
audio_type = avio_r8(pb); |
|
|
|
audio_type = avio_r8(pb); |
|
|
|
if (audio_type == 2) |
|
|
|
if (audio_type == 2) |
|
|
|
st->disposition |= AV_DISPOSITION_HEARING_IMPAIRED; |
|
|
|
st->disposition |= AV_DISPOSITION_HEARING_IMPAIRED; |
|
|
@ -851,7 +851,7 @@ static int parse_chunks(AVFormatContext *s, int mode, int64_t seekts, int *len_p |
|
|
|
} else if (!ff_guidcmp(g, EVENTID_DVBScramblingControlSpanningEvent)) { |
|
|
|
} else if (!ff_guidcmp(g, EVENTID_DVBScramblingControlSpanningEvent)) { |
|
|
|
int stream_index = ff_find_stream_index(s, sid); |
|
|
|
int stream_index = ff_find_stream_index(s, sid); |
|
|
|
if (stream_index >= 0) { |
|
|
|
if (stream_index >= 0) { |
|
|
|
url_fskip(pb, 12); |
|
|
|
avio_seek(pb, 12, SEEK_CUR); |
|
|
|
if (avio_rl32(pb)) |
|
|
|
if (avio_rl32(pb)) |
|
|
|
av_log(s, AV_LOG_WARNING, "DVB scrambled stream detected (st:%d), decoding will likely fail\n", stream_index); |
|
|
|
av_log(s, AV_LOG_WARNING, "DVB scrambled stream detected (st:%d), decoding will likely fail\n", stream_index); |
|
|
|
consumed += 16; |
|
|
|
consumed += 16; |
|
|
@ -861,7 +861,7 @@ static int parse_chunks(AVFormatContext *s, int mode, int64_t seekts, int *len_p |
|
|
|
if (stream_index >= 0) { |
|
|
|
if (stream_index >= 0) { |
|
|
|
AVStream *st = s->streams[stream_index]; |
|
|
|
AVStream *st = s->streams[stream_index]; |
|
|
|
uint8_t language[4]; |
|
|
|
uint8_t language[4]; |
|
|
|
url_fskip(pb, 12); |
|
|
|
avio_seek(pb, 12, SEEK_CUR); |
|
|
|
avio_read(pb, language, 3); |
|
|
|
avio_read(pb, language, 3); |
|
|
|
if (language[0]) { |
|
|
|
if (language[0]) { |
|
|
|
language[3] = 0; |
|
|
|
language[3] = 0; |
|
|
@ -874,7 +874,7 @@ static int parse_chunks(AVFormatContext *s, int mode, int64_t seekts, int *len_p |
|
|
|
} else if (!ff_guidcmp(g, timestamp_guid)) { |
|
|
|
} else if (!ff_guidcmp(g, timestamp_guid)) { |
|
|
|
int stream_index = ff_find_stream_index(s, sid); |
|
|
|
int stream_index = ff_find_stream_index(s, sid); |
|
|
|
if (stream_index >= 0) { |
|
|
|
if (stream_index >= 0) { |
|
|
|
url_fskip(pb, 8); |
|
|
|
avio_seek(pb, 8, SEEK_CUR); |
|
|
|
wtv->pts = avio_rl64(pb); |
|
|
|
wtv->pts = avio_rl64(pb); |
|
|
|
consumed += 16; |
|
|
|
consumed += 16; |
|
|
|
if (wtv->pts == -1) |
|
|
|
if (wtv->pts == -1) |
|
|
@ -885,7 +885,7 @@ static int parse_chunks(AVFormatContext *s, int mode, int64_t seekts, int *len_p |
|
|
|
wtv->epoch = wtv->pts; |
|
|
|
wtv->epoch = wtv->pts; |
|
|
|
if (mode == SEEK_TO_PTS && wtv->pts >= seekts) { |
|
|
|
if (mode == SEEK_TO_PTS && wtv->pts >= seekts) { |
|
|
|
#define WTV_PAD8(x) (((x) + 7) & ~7) |
|
|
|
#define WTV_PAD8(x) (((x) + 7) & ~7) |
|
|
|
url_fskip(pb, WTV_PAD8(len) - consumed); |
|
|
|
avio_seek(pb, WTV_PAD8(len) - consumed, SEEK_CUR); |
|
|
|
return 0; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -923,7 +923,7 @@ static int parse_chunks(AVFormatContext *s, int mode, int64_t seekts, int *len_p |
|
|
|
} else |
|
|
|
} else |
|
|
|
av_log(s, AV_LOG_WARNING, "unsupported chunk:"PRI_GUID"\n", ARG_GUID(g)); |
|
|
|
av_log(s, AV_LOG_WARNING, "unsupported chunk:"PRI_GUID"\n", ARG_GUID(g)); |
|
|
|
|
|
|
|
|
|
|
|
url_fskip(pb, WTV_PAD8(len) - consumed); |
|
|
|
avio_seek(pb, WTV_PAD8(len) - consumed, SEEK_CUR); |
|
|
|
} |
|
|
|
} |
|
|
|
return AVERROR_EOF; |
|
|
|
return AVERROR_EOF; |
|
|
|
} |
|
|
|
} |
|
|
@ -954,13 +954,13 @@ static int read_header(AVFormatContext *s, AVFormatParameters *ap) |
|
|
|
wtv->last_valid_pts = AV_NOPTS_VALUE; |
|
|
|
wtv->last_valid_pts = AV_NOPTS_VALUE; |
|
|
|
|
|
|
|
|
|
|
|
/* read root directory sector */ |
|
|
|
/* read root directory sector */ |
|
|
|
url_fskip(s->pb, 0x30); |
|
|
|
avio_seek(s->pb, 0x30, SEEK_CUR); |
|
|
|
root_size = avio_rl32(s->pb); |
|
|
|
root_size = avio_rl32(s->pb); |
|
|
|
if (root_size > sizeof(root)) { |
|
|
|
if (root_size > sizeof(root)) { |
|
|
|
av_log(s, AV_LOG_ERROR, "root directory size exceeds sector size\n"); |
|
|
|
av_log(s, AV_LOG_ERROR, "root directory size exceeds sector size\n"); |
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
} |
|
|
|
} |
|
|
|
url_fskip(s->pb, 4); |
|
|
|
avio_seek(s->pb, 4, SEEK_CUR); |
|
|
|
root_sector = avio_rl32(s->pb); |
|
|
|
root_sector = avio_rl32(s->pb); |
|
|
|
|
|
|
|
|
|
|
|
avio_seek(s->pb, root_sector << WTV_SECTOR_BITS, SEEK_SET); |
|
|
|
avio_seek(s->pb, root_sector << WTV_SECTOR_BITS, SEEK_SET); |
|
|
@ -1047,7 +1047,7 @@ static int read_packet(AVFormatContext *s, AVPacket *pkt) |
|
|
|
return ret; |
|
|
|
return ret; |
|
|
|
pkt->stream_index = stream_index; |
|
|
|
pkt->stream_index = stream_index; |
|
|
|
pkt->pts = wtv->pts; |
|
|
|
pkt->pts = wtv->pts; |
|
|
|
url_fskip(pb, WTV_PAD8(len) - len); |
|
|
|
avio_seek(pb, WTV_PAD8(len) - len, SEEK_CUR); |
|
|
|
return 0; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|