diff options
author | Zdenek Kabelac <kabi@informatics.muni.cz> | 2002-08-08 22:04:01 +0000 |
---|---|---|
committer | Zdenek Kabelac <kabi@informatics.muni.cz> | 2002-08-08 22:04:01 +0000 |
commit | 2141dc37d3ab5a6bf971885f4eeeed35a4dbe121 (patch) | |
tree | 8d66ef3d07191f6e053c25540a257f2db31d5da4 /libav/asf.c | |
parent | 2a10020bf332cff4af7e45cdded84728ac593361 (diff) | |
download | ffmpeg-2141dc37d3ab5a6bf971885f4eeeed35a4dbe121.tar.gz |
* added support for multiple payloads
Originally committed as revision 847 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libav/asf.c')
-rw-r--r-- | libav/asf.c | 115 |
1 files changed, 74 insertions, 41 deletions
diff --git a/libav/asf.c b/libav/asf.c index 7574fff4df..da1b306e9d 100644 --- a/libav/asf.c +++ b/libav/asf.c @@ -82,8 +82,8 @@ typedef struct { int seqno; int packet_size; int is_streamed; - int asfid2avid[128]; - ASFStream streams[128]; // it's max number + int asfid2avid[128]; /* conversion table from asf ID 2 AVStream ID */ + ASFStream streams[128]; /* it's max number and it's not that big */ /* non streamed additonnal info */ INT64 nb_packets; INT64 duration; /* in 100ns units */ @@ -111,6 +111,7 @@ typedef struct { int packet_frag_offset; int packet_frag_size; int packet_frag_timestamp; + int packet_multi_size; int packet_obj_size; int packet_time_delta; int packet_time_start; @@ -791,7 +792,7 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap) get_le32(pb); get_byte(pb); get_byte(pb); - + memset(&asf->asfid2avid, -1, sizeof(asf->asfid2avid)); for(;;) { get_guid(pb, &g); gsize = get_le64(pb); @@ -815,7 +816,8 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap) asf->hdr.min_pktsize = get_le32(pb); asf->hdr.max_pktsize = get_le32(pb); asf->hdr.max_bitrate = get_le32(pb); - asf->packet_size = asf->hdr.max_pktsize; + asf->packet_size = asf->hdr.max_pktsize; + asf->nb_packets = asf->hdr.packets_count; } else if (!memcmp(&g, &stream_header, sizeof(GUID))) { int type, id, total_size; unsigned int tag1; @@ -849,7 +851,8 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap) asf->asfid2avid[st->id] = s->nb_streams++; get_le32(pb); - st->codec.codec_type = type; + st->codec.codec_type = type; + st->codec.frame_rate = 1000; // in packet ticks if (type == CODEC_TYPE_AUDIO) { id = get_le16(pb); st->codec.codec_tag = id; @@ -860,13 +863,14 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap) bps = get_le16(pb); /* bits per sample */ st->codec.codec_id = wav_codec_get_id(id, bps); size = get_le16(pb); - st->extra_data = av_mallocz(size); - get_buffer(pb, st->extra_data, size); - st->extra_data_size = size; + if (size > 0) { + st->extra_data = av_mallocz(size); + get_buffer(pb, st->extra_data, size); + st->extra_data_size = size; + } /* We have to init the frame size at some point .... */ pos2 = url_ftell(pb); - if (gsize > (pos2 + 8 - pos1 + 24)) - { + if (gsize > (pos2 + 8 - pos1 + 24)) { asf_st->ds_span = get_byte(pb); asf_st->ds_packet_size = get_le16(pb); asf_st->ds_chunk_size = get_le16(pb); @@ -876,8 +880,7 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap) //printf("Descrambling: ps:%d cs:%d ds:%d s:%d sd:%d\n", // asf_st->ds_packet_size, asf_st->ds_chunk_size, // asf_st->ds_data_size, asf_st->ds_span, asf_st->ds_silence_data); - if (asf_st->ds_span > 1) - { + if (asf_st->ds_span > 1) { if (!asf_st->ds_chunk_size || (asf_st->ds_packet_size/asf_st->ds_chunk_size <= 1)) asf_st->ds_span = 0; // disable descrambling @@ -902,7 +905,7 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap) break; } } else { - get_le32(pb); + get_le32(pb); get_le32(pb); get_byte(pb); size = get_le16(pb); /* size */ @@ -910,13 +913,17 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap) st->codec.width = get_le32(pb); st->codec.height = get_le32(pb); /* not available for asf */ - st->codec.frame_rate = 25 * FRAME_RATE_BASE; /* XXX: find it */ get_le16(pb); /* panes */ get_le16(pb); /* depth */ tag1 = get_le32(pb); + url_fskip(pb, 20); + if (size > 40) { + st->extra_data_size = size - 40; + st->extra_data = av_mallocz(st->extra_data_size); + get_buffer(pb, st->extra_data, st->extra_data_size); + } st->codec.codec_tag = tag1; - st->codec.codec_id = codec_get_id(codec_asf_bmp_tags, tag1); - url_fskip(pb, size - 5 * 4); + st->codec.codec_id = codec_get_id(codec_asf_bmp_tags, tag1); } pos2 = url_ftell(pb); url_fskip(pb, gsize - (pos2 - pos1 + 24)); @@ -934,7 +941,7 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap) get_str16_nolen(pb, len2, s->author, sizeof(s->author)); get_str16_nolen(pb, len3, s->copyright, sizeof(s->copyright)); get_str16_nolen(pb, len4, s->comment, sizeof(s->comment)); - url_fskip(pb, len5); + url_fskip(pb, len5); #if 0 } else if (!memcmp(&g, &head1_guid, sizeof(GUID))) { int v1, v2; @@ -975,7 +982,9 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap) get_le64(pb); get_byte(pb); get_byte(pb); - + if (url_feof(pb)) + goto fail; + asf->data_offset = url_ftell(pb); asf->packet_size_left = 0; return 0; @@ -983,8 +992,10 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap) fail: for(i=0;i<s->nb_streams;i++) { AVStream *st = s->streams[i]; - if (st) - av_free(st->priv_data); + if (st) { + av_free(st->priv_data); + av_free(st->extra_data); + } av_free(st); } //av_free(asf); @@ -1029,7 +1040,7 @@ static int asf_get_packet(AVFormatContext *s) asf->packet_timestamp = get_le32(pb); get_le16(pb); /* duration */ - // rsize has 11 bytes static bytes which have to be present + // rsize has at least 11 bytes which have to be present if (asf->packet_flags & 0x01) { asf->packet_segsizetype = get_byte(pb); rsize++; @@ -1054,7 +1065,8 @@ static int asf_read_packet(AVFormatContext *s, AVPacket *pkt) static int pc = 0; for (;;) { int rsize = 0; - if (asf->packet_size_left < FRAME_HEADER_SIZE) { + if (asf->packet_size_left < FRAME_HEADER_SIZE + || asf->packet_segments < 0) { //asf->packet_size_left <= asf->packet_padsize) { int ret; //printf("PACKETLEFTSIZE %d\n", asf->packet_size_left); @@ -1067,11 +1079,15 @@ static int asf_read_packet(AVFormatContext *s, AVPacket *pkt) //printf("READ ASF PACKET %d r:%d c:%d\n", ret, asf->packet_size_left, pc++); if (ret < 0) return -EIO; + asf->packet_time_start = 0; continue; } - if (1) { // FIXME - handle replicated multi packets + if (asf->packet_time_start == 0) { + int num; + if (--asf->packet_segments < 0) + continue; /* read frame header */ - int num = get_byte(pb); + num = get_byte(pb); rsize++; asf->packet_key_frame = (num & 0x80) >> 7; asf->stream_index = asf->asfid2avid[num & 0x7f]; @@ -1080,9 +1096,8 @@ static int asf_read_packet(AVFormatContext *s, AVPacket *pkt) /* unhandled packet (should not happen) */ url_fskip(pb, asf->packet_frag_size); asf->packet_size_left -= asf->packet_frag_size; - //printf("#####xxxxxx###### skip %d\n", asf->packet_frag_size); + printf("ff asf skip %d %d\n", asf->packet_frag_size, num &0x7f); continue; - // FIXME } asf->asf_st = s->streams[asf->stream_index]->priv_data; //printf("ASFST %p %d <> %d\n", asf->asf_st, asf->stream_index, num & 0x7f); @@ -1101,6 +1116,7 @@ static int asf_read_packet(AVFormatContext *s, AVPacket *pkt) asf->packet_time_start = asf->packet_frag_offset; asf->packet_frag_offset = 0; asf->packet_frag_timestamp = asf->packet_timestamp; + if (asf->packet_replic_size == 1) { asf->packet_time_delta = get_byte(pb); rsize++; @@ -1114,6 +1130,15 @@ static int asf_read_packet(AVFormatContext *s, AVPacket *pkt) asf->packet_frag_size = asf->packet_size_left - rsize; //printf("Using rest %d %d %d\n", asf->packet_frag_size, asf->packet_size_left, rsize); } + if (asf->packet_replic_size == 1) + { + asf->packet_multi_size = asf->packet_frag_size; + if (asf->packet_multi_size > asf->packet_size_left) + { + asf->packet_segments = 0; + continue; + } + } #undef DO_2BITS asf->packet_size_left -= rsize; //printf("___objsize____ %d %d rs:%d\n", asf->packet_obj_size, asf->packet_frag_offset, rsize); @@ -1126,32 +1151,39 @@ static int asf_read_packet(AVFormatContext *s, AVPacket *pkt) ) { /* cannot continue current packet: free it */ // FIXME better check if packet was already allocated - printf("asf parser skips: %d - %d o:%d - %d %d %d fl:%d\n", + printf("ff asf parser skips: %d - %d o:%d - %d %d %d fl:%d\n", asf_st->pkt.size, - asf->packet_obj_size, + asf->packet_obj_size, asf->packet_frag_offset, asf_st->frag_offset, asf->packet_seq, asf_st->seq, asf->packet_frag_size); - if (asf_st->pkt.size) + if (asf_st->pkt.size) av_free_packet(&asf_st->pkt); asf_st->frag_offset = 0; if (asf->packet_frag_offset != 0) { - /* cannot create new packet */ url_fskip(pb, asf->packet_frag_size); - printf("asf parser skiping %db\n", asf->packet_frag_size); - asf->packet_size_left -= asf->packet_frag_size; + printf("ff asf parser skiping %db\n", asf->packet_frag_size); + asf->packet_size_left -= asf->packet_frag_size; continue; } } - if (asf->packet_replic_size == 1) - { - // frag_size is now begining timestamp + if (asf->packet_replic_size == 1) { + // frag_offset is here used as the begining timestamp asf->packet_frag_timestamp = asf->packet_time_start; + asf->packet_time_start += asf->packet_time_delta; asf->packet_obj_size = asf->packet_frag_size = get_byte(pb); - asf->packet_size_left--; - //printf("COMPRESS size %d %d\n", asf->packet_obj_size, asf->packet_frag_timestamp); + asf->packet_size_left--; + asf->packet_multi_size--; + if (asf->packet_multi_size < asf->packet_obj_size) + { + asf->packet_time_start = 0; + url_fskip(pb, asf->packet_multi_size); + asf->packet_size_left -= asf->packet_multi_size; + continue; + } + asf->packet_multi_size -= asf->packet_obj_size; + //printf("COMPRESS size %d %d %d ms:%d\n", asf->packet_obj_size, asf->packet_frag_timestamp, asf->packet_size_left, asf->packet_multi_size); } - //printf("PACKET OFFSET %d\n", asf_st->frag_offset); if (asf_st->frag_offset == 0) { /* new packet */ av_new_packet(&asf_st->pkt, asf->packet_obj_size); @@ -1166,15 +1198,17 @@ static int asf_read_packet(AVFormatContext *s, AVPacket *pkt) //printf("READ PACKET s:%d os:%d o:%d,%d l:%d DATA:%p\n", // asf->packet_size, asf_st->pkt.size, asf->packet_frag_offset, // asf_st->frag_offset, asf->packet_frag_size, asf_st->pkt.data); + asf->packet_size_left -= asf->packet_frag_size; + if (asf->packet_size_left < 0) + continue; get_buffer(pb, asf_st->pkt.data + asf->packet_frag_offset, asf->packet_frag_size); asf_st->frag_offset += asf->packet_frag_size; - asf->packet_size_left -= asf->packet_frag_size; /* test if whole packet is read */ if (asf_st->frag_offset == asf_st->pkt.size) { /* return packet */ if (asf_st->ds_span > 1) { - // descramble packet + /* packet descrambling */ char* newdata = av_malloc(asf_st->pkt.size); if (newdata) { int offset = 0; @@ -1199,7 +1233,6 @@ static int asf_read_packet(AVFormatContext *s, AVPacket *pkt) //printf("packet %d %d\n", asf_st->pkt.size, asf->packet_frag_size); asf_st->pkt.size = 0; asf_st->pkt.data = 0; - // FIXME descrambling break; // packet completed } } |