diff options
author | Thibaut Mattern <tmattern@users.sourceforge.net> | 2004-11-01 15:53:52 +0000 |
---|---|---|
committer | Thibaut Mattern <tmattern@users.sourceforge.net> | 2004-11-01 15:53:52 +0000 |
commit | 9fd0b8f5cfa2f20a9cd7f3bd4a1490093fd730c0 (patch) | |
tree | eb9858c199f1ac0cd5ad48211299693bd1225ce9 /src | |
parent | b5916a63216198c12e2431610de34e12f0a76035 (diff) | |
download | xine-lib-9fd0b8f5cfa2f20a9cd7f3bd4a1490093fd730c0.tar.gz xine-lib-9fd0b8f5cfa2f20a9cd7f3bd4a1490093fd730c0.tar.bz2 |
Fixed packet seq handling.
Fixed bug reported by Daniel (http://naboo.homelinux.org/~daniel/samples/TimsTraySlide.asf).
CVS patchset: 7099
CVS date: 2004/11/01 15:53:52
Diffstat (limited to 'src')
-rw-r--r-- | src/demuxers/demux_asf.c | 181 |
1 files changed, 76 insertions, 105 deletions
diff --git a/src/demuxers/demux_asf.c b/src/demuxers/demux_asf.c index 8a919ae8e..1723d787e 100644 --- a/src/demuxers/demux_asf.c +++ b/src/demuxers/demux_asf.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: demux_asf.c,v 1.162 2004/09/02 19:56:41 valtri Exp $ + * $Id: demux_asf.c,v 1.163 2004/11/01 15:53:52 tmattern Exp $ * * demultiplexer for asf streams * @@ -96,6 +96,8 @@ typedef struct { xine_bmiheader *bih; int bih_size; + int payload_size; + } asf_stream_t; typedef struct demux_asf_s { @@ -786,39 +788,29 @@ static void check_newpts (demux_asf_t *this, int64_t pts, int video, int frame_e static void asf_send_buffer_nodefrag (demux_asf_t *this, asf_stream_t *stream, - int frag_offset, int seq, - int64_t timestamp, - int frag_len, int payload_size) { + int frag_offset, int64_t timestamp, + int frag_len) { buf_element_t *buf; int bufsize; int package_done; - lprintf ("pts=%lld, seq=%d, off=%d, len=%d, total=%d\n", - timestamp * 90, seq, frag_offset, frag_len, payload_size); + lprintf ("pts=%lld, off=%d, len=%d, total=%d\n", + timestamp * 90, frag_offset, frag_len, stream->payload_size); - if ((stream->frag_offset == 0) && (frag_offset == 0)) { + if (frag_offset == 0) { /* new packet */ - stream->seq = seq; + stream->frag_offset = 0; + lprintf("new packet\n"); } else { - if (seq == stream->seq && - frag_offset == stream->frag_offset) { + if (frag_offset == stream->frag_offset) { /* continuing packet */ + lprintf("continuing packet: offset=%d\n", frag_offset); } else { /* cannot continue current packet: free it */ - if (frag_offset != 0) { - /* cannot create new packet, will die soon */ - xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: asf_send_buffer_nodefrag: invalid offset\n"); - this->input->seek (this->input, frag_len, SEEK_CUR); - return ; - - } else { - /* create new packet */ - xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, - "demux_asf: asf_send_buffer_nodefrag: packet not complete\n"); - stream->seq = seq; - stream->frag_offset = 0; - } + xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: asf_send_buffer_nodefrag: stream offset: %d, invalid offset: %d\n", stream->frag_offset, frag_offset); + this->input->seek (this->input, frag_len, SEEK_CUR); + return ; } } @@ -838,7 +830,7 @@ static void asf_send_buffer_nodefrag (demux_asf_t *this, asf_stream_t *stream, 65535 / this->input->get_length (this->input) ); buf->extra_info->input_time = timestamp; - lprintf ("input normpos is %lld, input time is %d, rate %d\n", + lprintf ("input normpos is %d, input time is %d, rate %d\n", buf->extra_info->input_normpos, buf->extra_info->input_time, this->rate); @@ -851,7 +843,7 @@ static void asf_send_buffer_nodefrag (demux_asf_t *this, asf_stream_t *stream, stream->frag_offset += bufsize; frag_len -= bufsize; - package_done = (stream->frag_offset >= payload_size); + package_done = (stream->frag_offset >= stream->payload_size); if ((buf->type & BUF_MAJOR_MASK) == BUF_VIDEO_BASE) check_newpts (this, buf->pts, PTS_VIDEO, package_done); @@ -864,9 +856,8 @@ static void asf_send_buffer_nodefrag (demux_asf_t *this, asf_stream_t *stream, /* test if whole packet read */ if (package_done) { - buf->decoder_flags |= BUF_FLAG_FRAME_END; - stream->frag_offset = 0; + lprintf("packet done: offset=%d, payload=%d\n", stream->frag_offset, stream->payload_size); } lprintf ("buffer type %08x %8d bytes, %8lld pts\n", @@ -877,9 +868,8 @@ static void asf_send_buffer_nodefrag (demux_asf_t *this, asf_stream_t *stream, } static void asf_send_buffer_defrag (demux_asf_t *this, asf_stream_t *stream, - int frag_offset, int seq, - int64_t timestamp, - int frag_len, int payload_size) { + int frag_offset, int64_t timestamp, + int frag_len) { buf_element_t *buf; int package_done; @@ -890,28 +880,20 @@ static void asf_send_buffer_defrag (demux_asf_t *this, asf_stream_t *stream, */ lprintf ("asf_send_buffer_defrag: timestamp=%lld, pts=%lld\n", timestamp, timestamp * 90); - if ((stream->frag_offset == 0) && (frag_offset == 0)) { + if (frag_offset == 0) { /* new packet */ - stream->seq = seq; + lprintf("new packet\n"); + stream->frag_offset = 0; stream->timestamp = timestamp; } else { - if (seq == stream->seq && - frag_offset == stream->frag_offset) { + if (frag_offset == stream->frag_offset) { /* continuing packet */ + lprintf("continuing packet: offset=%d\n", frag_offset); } else { /* cannot continue current packet: free it */ - if (frag_offset != 0) { - /* cannot create new packet, will die soon */ - xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: asf_send_buffer_defrag: invalid offset\n"); - this->input->seek (this->input, frag_len, SEEK_CUR); - return ; - - } else { - /* create new packet */ - xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: asf_send_buffer_defrag: packet not complete\n"); - stream->seq = seq; - stream->frag_offset = 0; - } + xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: asf_send_buffer_defrag: invalid offset\n"); + this->input->seek (this->input, frag_len, SEEK_CUR); + return ; } } @@ -922,13 +904,14 @@ static void asf_send_buffer_defrag (demux_asf_t *this, asf_stream_t *stream, stream->frag_offset += frag_len; } - package_done = (stream->frag_offset >= payload_size); + package_done = (stream->frag_offset >= stream->payload_size); - if (package_done) - { + if (package_done) { int bufsize; uint8_t *p; + lprintf("packet done: offset=%d, payload=%d\n", stream->frag_offset, stream->payload_size); + if (stream->fifo == this->audio_fifo && this->reorder_h > 1 && this->reorder_w > 1 ) { asf_reorder(this,stream->buffer,stream->frag_offset); @@ -949,12 +932,6 @@ static void asf_send_buffer_defrag (demux_asf_t *this, asf_stream_t *stream, 65535 / this->input->get_length (this->input) ); buf->extra_info->input_time = stream->timestamp; -#if 0 - /* tm: not needed */ - buf->pts = stream->timestamp * 90 + stream->ts_per_kbyte * - (p-stream->buffer) / 1024; - -#endif /* send the same pts for the entire frame */ buf->pts = stream->timestamp * 90; @@ -1160,15 +1137,15 @@ static int asf_parse_packet_payload_header(demux_asf_t *this, uint32_t p_hdr_siz /* return 0 if ok */ static int asf_parse_packet_payload_common(demux_asf_t *this, - uint8_t raw_id, - asf_stream_t **stream, - uint32_t *frag_offset, - uint32_t *rlen, - uint32_t *seq) { + uint8_t raw_id, + asf_stream_t **stream, + uint32_t *frag_offset, + uint32_t *rlen) { uint8_t stream_id; int i; uint32_t s_hdr_size = 0; - uint32_t exp_seq = 0; + uint32_t seq = 0; + uint32_t next_seq = 0; buf_element_t *buf; stream_id = raw_id & 0x7f; @@ -1198,38 +1175,39 @@ static int asf_parse_packet_payload_common(demux_asf_t *this, switch ((this->packet_prop_flags >> 4) & 3){ case 1: - *seq = get_byte(this); s_hdr_size += 1; - if (*stream) - exp_seq = ((*stream)->seq + 1) % 256; + seq = get_byte(this); s_hdr_size += 1; + if (*stream) { + (*stream)->seq = (*stream)->seq % 256; + next_seq = ((*stream)->seq + 1) % 256; + } break; case 2: - *seq = get_le16(this); s_hdr_size += 2; - if (*stream) - exp_seq = ((*stream)->seq + 1) % 65536; + seq = get_le16(this); s_hdr_size += 2; + if (*stream) { + (*stream)->seq = (*stream)->seq % 65536; + next_seq = ((*stream)->seq + 1) % 65536; + } break; case 3: - *seq = get_le32(this); s_hdr_size += 4; + seq = get_le32(this); s_hdr_size += 4; if (*stream) - exp_seq = (*stream)->seq + 1; + next_seq = (*stream)->seq + 1; break; default: lprintf ("seq=0\n"); - *seq = 0; + seq = 0; } /* check seq number */ if (*stream) { - lprintf ("stream_id = %d, seq = %d\n", (*stream)->stream_id, *seq); + lprintf ("stream_id = %d, seq = %d\n", (*stream)->stream_id, seq); if ((*stream)->first_seq || (*stream)->skip) { - exp_seq = *seq; + next_seq = seq; (*stream)->first_seq = 0; - } else if ((*stream)->frag_offset) { - /* should be the same seq */ - exp_seq = (*stream)->seq; } - if (exp_seq != *seq) { + if ((seq != (*stream)->seq) && (seq != next_seq)) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, - "demux_asf: bad seq: seq = %d, expected = %d, stream seq = %d!\n", *seq, exp_seq, (*stream)->seq); + "demux_asf: bad seq: seq = %d, next_seq = %d, stream seq = %d!\n", seq, next_seq, (*stream)->seq); /* the stream is corrupted, reset the decoder and restart at a new keyframe */ if ((*stream)->fifo) { @@ -1245,6 +1223,7 @@ static int asf_parse_packet_payload_common(demux_asf_t *this, this->keyframe_found = 0; } } + (*stream)->seq = seq; } switch ((this->packet_prop_flags >> 2) & 3) { @@ -1288,7 +1267,6 @@ static int asf_parse_packet_compressed_payload(demux_asf_t *this, asf_stream_t *stream, uint8_t raw_id, uint32_t frag_offset, - uint32_t seq, int64_t *timestamp) { uint32_t s_hdr_size = 0; uint32_t data_length = 0; @@ -1337,6 +1315,8 @@ static int asf_parse_packet_compressed_payload(demux_asf_t *this, lprintf ("sending grouped object, len = %d\n", object_length); if (stream && stream->fifo) { + stream->payload_size = object_length; + /* keyframe detection for non-seekable input plugins */ if (stream->skip && (raw_id & 0x80) && !this->keyframe_found) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: keyframe detected\n"); @@ -1354,22 +1334,20 @@ static int asf_parse_packet_compressed_payload(demux_asf_t *this, lprintf ("sending buffer of type %08x\n", stream->buf_type); if (stream->defrag) - asf_send_buffer_defrag (this, stream, 0, seq, *timestamp, - object_length, object_length); + asf_send_buffer_defrag (this, stream, 0, *timestamp, object_length); else - asf_send_buffer_nodefrag (this, stream, 0, seq, *timestamp, - object_length, object_length); + asf_send_buffer_nodefrag (this, stream, 0, *timestamp, object_length); } else { lprintf ("skip object\n"); this->input->seek (this->input, object_length, SEEK_CUR); } + stream->seq++; } else { lprintf ("unhandled stream type\n"); this->input->seek (this->input, object_length, SEEK_CUR); } - seq++; data_sent += object_length + 1; this->packet_size_left -= object_length + 1; *timestamp = 0; @@ -1384,22 +1362,23 @@ static int asf_parse_packet_payload(demux_asf_t *this, uint8_t raw_id, uint32_t frag_offset, uint32_t rlen, - uint32_t seq, int64_t *timestamp) { uint32_t s_hdr_size = 0; - uint32_t payload_size, frag_len; + uint32_t frag_len; + uint32_t payload_size = 0; if (rlen >= 8) { payload_size = get_le32(this); s_hdr_size += 4; *timestamp = get_le32(this); s_hdr_size += 4; if (*timestamp) *timestamp -= this->preroll; - - if (rlen - 8) this->input->seek (this->input, rlen - 8, SEEK_CUR); + if (stream) + stream->payload_size = payload_size; + if ((rlen - 8) > 0) + this->input->seek (this->input, rlen - 8, SEEK_CUR); s_hdr_size += rlen - 8; } else { - *timestamp = 0; - payload_size = 0; + *timestamp = 0; if (rlen) this->input->seek (this->input, rlen, SEEK_CUR); s_hdr_size += rlen; } @@ -1431,10 +1410,6 @@ static int asf_parse_packet_payload(demux_asf_t *this, return 1; } - if (!payload_size) { - payload_size = frag_len; - } - this->packet_size_left -= s_hdr_size; if (stream && stream->fifo) { @@ -1457,11 +1432,9 @@ static int asf_parse_packet_payload(demux_asf_t *this, lprintf ("sending buffer of type %08x\n", stream->buf_type); if (stream->defrag) - asf_send_buffer_defrag (this, stream, frag_offset, seq, *timestamp, - frag_len, payload_size); + asf_send_buffer_defrag (this, stream, frag_offset, *timestamp, frag_len); else - asf_send_buffer_nodefrag (this, stream, frag_offset, seq, *timestamp, - frag_len, payload_size); + asf_send_buffer_nodefrag (this, stream, frag_offset, *timestamp, frag_len); } else { lprintf ("skip fragment\n"); @@ -1761,7 +1734,6 @@ static int demux_asf_send_chunk (demux_plugin_t *this_gen) { asf_stream_t *stream = NULL; uint32_t frag_offset = 0; uint32_t rlen = 0; - uint32_t seq = 0; uint8_t raw_id = 0; int64_t ts = 0; @@ -1802,13 +1774,13 @@ static int demux_asf_send_chunk (demux_plugin_t *this_gen) { for (this->frame = 0; this->frame < (this->nb_frames & 0x3f); this->frame++) { raw_id = get_byte(this); this->packet_size_left -= 1; - if (asf_parse_packet_payload_common(this, raw_id, &stream, &frag_offset, &rlen, &seq)) + if (asf_parse_packet_payload_common(this, raw_id, &stream, &frag_offset, &rlen)) break; if (rlen == 1) { - if (asf_parse_packet_compressed_payload(this, stream, raw_id, frag_offset, seq, &ts)) + if (asf_parse_packet_compressed_payload(this, stream, raw_id, frag_offset, &ts)) break; } else { - if (asf_parse_packet_payload(this, stream, raw_id, frag_offset, rlen, seq, &ts)) + if (asf_parse_packet_payload(this, stream, raw_id, frag_offset, rlen, &ts)) break; } } @@ -1893,7 +1865,6 @@ static int demux_asf_seek (demux_plugin_t *this_gen, asf_stream_t *stream = NULL; uint32_t frag_offset = 0; uint32_t rlen = 0; - uint32_t seq = 0; uint8_t raw_id, stream_id; int i, state; int64_t ts; @@ -1990,14 +1961,14 @@ static int demux_asf_seek (demux_plugin_t *this_gen, lprintf ("demux_asf_seek: raw_id = %d\n", raw_id); stream_id = raw_id & 0x7f; - if (asf_parse_packet_payload_common(this, raw_id, &stream, &frag_offset, &rlen, &seq)) + if (asf_parse_packet_payload_common(this, raw_id, &stream, &frag_offset, &rlen)) break; if (rlen == 1) { - if (asf_parse_packet_compressed_payload(this, stream, raw_id, frag_offset, seq, &ts)) + if (asf_parse_packet_compressed_payload(this, stream, raw_id, frag_offset, &ts)) break; } else { - if (asf_parse_packet_payload(this, stream, raw_id, frag_offset, rlen, seq, &ts)) + if (asf_parse_packet_payload(this, stream, raw_id, frag_offset, rlen, &ts)) break; } |