summaryrefslogtreecommitdiff
path: root/libavformat/asfdec.c
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2012-11-03 05:37:18 +0100
committerMichael Niedermayer <michaelni@gmx.at>2012-11-03 05:37:18 +0100
commit8c93269e420735f41363e75f8ee4c4e7b3ec49a7 (patch)
tree272be20adef5a2289c4d727aedf9fbb2e313f82a /libavformat/asfdec.c
parent2d8c76eb1f1c198e81c36a95c0d56e55cc1f4c5a (diff)
asfdec: correctly parse payload extensions
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavformat/asfdec.c')
-rw-r--r--libavformat/asfdec.c50
1 files changed, 39 insertions, 11 deletions
diff --git a/libavformat/asfdec.c b/libavformat/asfdec.c
index 4ad5c2dfd7..30e2a50b43 100644
--- a/libavformat/asfdec.c
+++ b/libavformat/asfdec.c
@@ -926,13 +926,16 @@ static int ff_asf_get_packet(AVFormatContext *s, AVIOContext *pb)
*/
static int asf_read_frame_header(AVFormatContext *s, AVIOContext *pb){
ASFContext *asf = s->priv_data;
+ ASFStream *asfst;
int rsize = 1;
int num = avio_r8(pb);
+ int i;
int64_t ts0, ts1 av_unused;
asf->packet_segments--;
asf->packet_key_frame = num >> 7;
asf->stream_index = asf->asfid2avid[num & 0x7f];
+ asfst = &asf->streams[num & 0x7f];
// sequence should be ignored!
DO_2BITS(asf->packet_property >> 4, asf->packet_seq, 0);
DO_2BITS(asf->packet_property >> 2, asf->packet_frag_offset, 0);
@@ -945,23 +948,48 @@ static int asf_read_frame_header(AVFormatContext *s, AVIOContext *pb){
return AVERROR_INVALIDDATA;
}
if (asf->packet_replic_size >= 8) {
+ int64_t end = avio_tell(pb) + asf->packet_replic_size;
asf->packet_obj_size = avio_rl32(pb);
if(asf->packet_obj_size >= (1<<24) || asf->packet_obj_size <= 0){
av_log(s, AV_LOG_ERROR, "packet_obj_size invalid\n");
return AVERROR_INVALIDDATA;
}
asf->packet_frag_timestamp = avio_rl32(pb); // timestamp
- if(asf->packet_replic_size >= 8+38+4){
- avio_skip(pb, 10);
- ts0= avio_rl64(pb);
- ts1= avio_rl64(pb);
- avio_skip(pb, 12);
- avio_rl32(pb);
- avio_skip(pb, asf->packet_replic_size - 8 - 38 - 4);
- if(ts0!= -1) asf->packet_frag_timestamp= ts0/10000;
- else asf->packet_frag_timestamp= AV_NOPTS_VALUE;
- }else
- avio_skip(pb, asf->packet_replic_size - 8);
+
+ for (i=0; i<asfst->payload_ext_ct; i++) {
+ ASFPayload *p = &asfst->payload[i];
+ int size = p->size;
+ int64_t payend;
+ if(size == 0xFFFF)
+ size = avio_rl16(pb);
+ payend = avio_tell(pb) + size;
+ if (payend > end) {
+ av_log(s, AV_LOG_ERROR, "too long payload\n");
+ break;
+ }
+ switch(p->type) {
+ case 0x50:
+// duration = avio_rl16(pb);
+ break;
+ case 0x2A:
+ avio_skip(pb, 8);
+ ts0= avio_rl64(pb);
+ ts1= avio_rl64(pb);
+ if(ts0!= -1) asf->packet_frag_timestamp= ts0/10000;
+ else asf->packet_frag_timestamp= AV_NOPTS_VALUE;
+ break;
+ case 0x5B:
+ case 0xB7:
+ case 0xCC:
+ case 0xC0:
+ case 0xA0:
+ //unknown
+ break;
+ }
+ avio_seek(pb, payend, SEEK_SET);
+ }
+
+ avio_seek(pb, end, SEEK_SET);
rsize += asf->packet_replic_size; // FIXME - check validity
} else if (asf->packet_replic_size==1){
// multipacket - frag_offset is beginning timestamp