Mercurial > mplayer.hg
comparison spudec.c @ 7743:a280cc3087ea
All right: The patch adresses two issues which I found, when I analyzed
the input from some DVDs with known subtitle-dropouts:
1. The packet-size at the beginning of the packet, which is used to
check, whether we got all fragments, is sometimes one byte too long. It
seems to be always padded to an even number, while the actual size can
be odd.
2. The original algorythm used to assemble the fragments relies on the
timestamps to check, whether a new packet begins. This has proven to be
unrelieable on some disks. So instead, I use the timestamp only to
check, whether it's been too long (defined as 0,01sec) since the last
fragment, which is probably indicating a broken packet, and normaly
starting a new packet when the last one has been finished.
patch by Christof Buergi <christof@buergi.lugs.ch>
author | arpi |
---|---|
date | Tue, 15 Oct 2002 00:47:17 +0000 |
parents | d796833e77af |
children | c70444c5b516 |
comparison
equal
deleted
inserted
replaced
7742:dafb8a59eee5 | 7743:a280cc3087ea |
---|---|
417 // spudec_heartbeat(this, pts100); | 417 // spudec_heartbeat(this, pts100); |
418 if (len < 2) { | 418 if (len < 2) { |
419 mp_msg(MSGT_SPUDEC,MSGL_WARN,"SPUasm: packet too short\n"); | 419 mp_msg(MSGT_SPUDEC,MSGL_WARN,"SPUasm: packet too short\n"); |
420 return; | 420 return; |
421 } | 421 } |
422 if (spu->packet_pts < pts100) { | 422 if ((spu->packet_pts + 10000) < pts100) { |
423 spu->packet_pts = pts100; | 423 // [cb] too long since last fragment: force new packet |
424 spu->packet_offset = 0; | 424 spu->packet_offset = 0; |
425 } | 425 } |
426 spu->packet_pts = pts100; | |
426 if (spu->packet_offset == 0) { | 427 if (spu->packet_offset == 0) { |
427 unsigned int len2 = get_be16(packet); | 428 unsigned int len2 = get_be16(packet); |
428 // Start new fragment | 429 // Start new fragment |
429 if (spu->packet_reserve < len2) { | 430 if (spu->packet_reserve < len2) { |
430 if (spu->packet != NULL) | 431 if (spu->packet != NULL) |
454 } | 455 } |
455 } | 456 } |
456 #if 1 | 457 #if 1 |
457 // check if we have a complete packet (unfortunatelly packet_size is bad | 458 // check if we have a complete packet (unfortunatelly packet_size is bad |
458 // for some disks) | 459 // for some disks) |
459 if (spu->packet_offset == spu->packet_size){ | 460 // [cb] packet_size is padded to be even -> may be one byte too long |
461 if ((spu->packet_offset == spu->packet_size) || | |
462 ((spu->packet_offset + 1) == spu->packet_size)){ | |
460 unsigned int x=0,y; | 463 unsigned int x=0,y; |
461 while(x+4<=spu->packet_offset){ | 464 while(x+4<=spu->packet_offset){ |
462 y=get_be16(spu->packet+x+2); // next control pointer | 465 y=get_be16(spu->packet+x+2); // next control pointer |
463 mp_msg(MSGT_SPUDEC,MSGL_DBG2,"SPUtest: x=%d y=%d off=%d size=%d\n",x,y,spu->packet_offset,spu->packet_size); | 466 mp_msg(MSGT_SPUDEC,MSGL_DBG2,"SPUtest: x=%d y=%d off=%d size=%d\n",x,y,spu->packet_offset,spu->packet_size); |
464 if(x>=4 && x==y){ // if it points to self - we're done! | 467 if(x>=4 && x==y){ // if it points to self - we're done! |
473 spu->packet_size = spu->packet_offset = 0; | 476 spu->packet_size = spu->packet_offset = 0; |
474 break; | 477 break; |
475 } | 478 } |
476 x=y; | 479 x=y; |
477 } | 480 } |
481 // [cb] packet is done; start new packet | |
482 spu->packet_offset = 0; | |
478 } | 483 } |
479 #else | 484 #else |
480 if (spu->packet_offset == spu->packet_size) { | 485 if (spu->packet_offset == spu->packet_size) { |
481 spudec_decode(spu, pts100); | 486 spudec_decode(spu, pts100); |
482 spu->packet_offset = 0; | 487 spu->packet_offset = 0; |