summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2011-02-03 03:14:12 +0000
committerMichael Sevakis <jethead71@rockbox.org>2011-02-03 03:14:12 +0000
commit1bb3d61ef372e00986dd03672de944f756aeab4a (patch)
treeaf10850b35171fdcc4278c57c36139cf7ee6ffb4 /apps
parent38084784ad70a783ca1aae228007ed0b5abb31e4 (diff)
downloadrockbox-1bb3d61ef372e00986dd03672de944f756aeab4a.tar.gz
rockbox-1bb3d61ef372e00986dd03672de944f756aeab4a.zip
MPEGPlayer: Try out a different frame drop scheme meant to skip in a more uniform way rather than running up late and jumping forward; will often drop more in long term to keep up in short term. Some other obscure fixes included: wait for 2 ref pics before decoding B-pics again after P or I frame drop or seeking (issue with open GOPs); draw the frame the decoder already has when beginning playback after a seek; rename a few vars.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29198 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
-rw-r--r--apps/plugins/mpegplayer/video_thread.c408
1 files changed, 216 insertions, 192 deletions
diff --git a/apps/plugins/mpegplayer/video_thread.c b/apps/plugins/mpegplayer/video_thread.c
index aa88590b8e..2bfc5c680b 100644
--- a/apps/plugins/mpegplayer/video_thread.c
+++ b/apps/plugins/mpegplayer/video_thread.c
@@ -32,20 +32,26 @@
32/* Video thread data passed around to its various functions */ 32/* Video thread data passed around to its various functions */
33struct video_thread_data 33struct video_thread_data
34{ 34{
35 /* Stream data */
35 mpeg2dec_t *mpeg2dec; /* Our video decoder */ 36 mpeg2dec_t *mpeg2dec; /* Our video decoder */
36 const mpeg2_info_t *info; /* Info about video stream */ 37 const mpeg2_info_t *info; /* Info about video stream */
37 int state; /* Thread state */ 38 int state; /* Thread state */
38 int status; /* Media status */ 39 int status; /* Media status */
39 struct queue_event ev; /* Our event queue to receive commands */ 40 struct queue_event ev;/* Our event queue to receive commands */
40 uint32_t eta_stream; /* Current time of stream */ 41 /* Operational info */
41 uint32_t eta_video; /* Time that frame has been scheduled for */ 42 uint32_t stream_time; /* Current time from beginning of stream */
42 int32_t eta_early; /* How early has the frame been decoded? */ 43 uint32_t goal_time; /* Scheduled time of current frame */
43 int32_t eta_late; /* How late has the frame been decoded? */ 44 int32_t remain_time; /* T-minus value to frame_time (-:early, +:late) */
44 int frame_drop_level; /* Drop severity */ 45 int skip_ref_pics; /* Severe skipping - wait for I-frame */
45 int skip_level; /* Skip severity */ 46 int skip_level; /* Number of frames still to skip */
46 long last_render; /* Last time a frame was drawn */ 47 int num_picture; /* Number of picture headers read */
47 uint32_t curr_time; /* Current due time of frame */ 48 int num_intra; /* Number of I-picture headers read */
48 uint32_t period; /* Frame period in clock ticks */ 49 int group_est; /* Estmated number remaining as of last I */
50 long last_render; /* Last time a frame was drawn */
51 /* Sync info */
52 uint32_t frame_time; /* Current due time of frame (unadjusted) */
53 uint32_t frame_period; /* Frame period in clock ticks */
54 int num_ref_pics; /* Number of I and P frames since sync/skip */
49 int syncf_perfect; /* Last sync fit result */ 55 int syncf_perfect; /* Last sync fit result */
50}; 56};
51 57
@@ -62,6 +68,10 @@ static struct event_queue video_str_queue SHAREDBSS_ATTR;
62static struct queue_sender_list video_str_queue_send SHAREDBSS_ATTR; 68static struct queue_sender_list video_str_queue_send SHAREDBSS_ATTR;
63struct stream video_str IBSS_ATTR; 69struct stream video_str IBSS_ATTR;
64 70
71#define DEFAULT_GOP_SIZE INT_MAX /* no I/P skips until it learns */
72#define DROP_THRESHOLD (100*TS_SECOND/1000)
73#define MAX_EARLINESS (120*TS_SECOND/1000)
74
65#if defined(DEBUG) || defined(SIMULATOR) 75#if defined(DEBUG) || defined(SIMULATOR)
66static unsigned char pic_coding_type_char(unsigned type) 76static unsigned char pic_coding_type_char(unsigned type)
67{ 77{
@@ -217,12 +227,12 @@ static bool check_needs_sync(struct video_thread_data *td, uint32_t time)
217 } 227 }
218 228
219 time = clip_time(&video_str, time); 229 time = clip_time(&video_str, time);
220 end_time = td->curr_time + td->period; 230 end_time = td->frame_time + td->frame_period;
221 231
222 DEBUGF(" sft:%u t:%u sfte:%u\n", (unsigned)td->curr_time, 232 DEBUGF(" sft:%u t:%u sfte:%u\n", (unsigned)td->frame_time,
223 (unsigned)time, (unsigned)end_time); 233 (unsigned)time, (unsigned)end_time);
224 234
225 if (time < td->curr_time) 235 if (time < td->frame_time)
226 return true; 236 return true;
227 237
228 if (time >= end_time) 238 if (time >= end_time)
@@ -236,12 +246,12 @@ static int sync_decoder(struct video_thread_data *td,
236 struct str_sync_data *sd) 246 struct str_sync_data *sd)
237{ 247{
238 int retval = STREAM_ERROR; 248 int retval = STREAM_ERROR;
239 int ipic = 0, ppic = 0;
240 uint32_t time = clip_time(&video_str, sd->time); 249 uint32_t time = clip_time(&video_str, sd->time);
241 250
242 td->syncf_perfect = 0; 251 td->syncf_perfect = 0;
243 td->curr_time = 0; 252 td->frame_time = 0;
244 td->period = 0; 253 td->frame_period = 0;
254 td->num_ref_pics = 0;
245 255
246 /* Sometimes theres no sequence headers nearby and libmpeg2 may have reset 256 /* Sometimes theres no sequence headers nearby and libmpeg2 may have reset
247 * fully at some point */ 257 * fully at some point */
@@ -281,7 +291,6 @@ static int sync_decoder(struct video_thread_data *td,
281 case STREAM_OK: 291 case STREAM_OK:
282 if (video_str.pkt_flags & PKT_HAS_TS) 292 if (video_str.pkt_flags & PKT_HAS_TS)
283 mpeg2_tag_picture(td->mpeg2dec, video_str.pts, 0); 293 mpeg2_tag_picture(td->mpeg2dec, video_str.pts, 0);
284
285 mpeg2_buffer(td->mpeg2dec, video_str.curr_packet, 294 mpeg2_buffer(td->mpeg2dec, video_str.curr_packet,
286 video_str.curr_packet_end); 295 video_str.curr_packet_end);
287 td->info = mpeg2_info(td->mpeg2dec); 296 td->info = mpeg2_info(td->mpeg2dec);
@@ -310,11 +319,13 @@ static int sync_decoder(struct video_thread_data *td,
310 case PIC_FLAG_CODING_TYPE_I: 319 case PIC_FLAG_CODING_TYPE_I:
311 /* I-frame; start decoding */ 320 /* I-frame; start decoding */
312 mpeg2_skip(td->mpeg2dec, 0); 321 mpeg2_skip(td->mpeg2dec, 0);
313 ipic = 1; 322 td->num_ref_pics++;
314 break; 323 break;
324
315 case PIC_FLAG_CODING_TYPE_P: 325 case PIC_FLAG_CODING_TYPE_P:
316 /* P-frames don't count without I-frames */ 326 /* P-frames don't count without I-frames */
317 ppic = ipic; 327 if (td->num_ref_pics > 0)
328 td->num_ref_pics++;
318 break; 329 break;
319 } 330 }
320 331
@@ -348,26 +359,26 @@ static int sync_decoder(struct video_thread_data *td,
348 359
349 if (td->info->display_picture->flags & PIC_FLAG_TAGS) 360 if (td->info->display_picture->flags & PIC_FLAG_TAGS)
350 { 361 {
351 td->curr_time = td->info->display_picture->tag; 362 td->frame_time = td->info->display_picture->tag;
352 DEBUGF(" frame tagged:%u (%c%s)\n", (unsigned)td->curr_time, 363 DEBUGF(" frame tagged:%u (%c%s)\n", (unsigned)td->frame_time,
353 pic_coding_type_char(type), 364 pic_coding_type_char(type),
354 (td->info->display_picture->flags & PIC_FLAG_SKIP) ? 365 (td->info->display_picture->flags & PIC_FLAG_SKIP) ?
355 " skipped" : ""); 366 " skipped" : "");
356 } 367 }
357 else 368 else
358 { 369 {
359 td->curr_time += td->period; 370 td->frame_time += td->frame_period;
360 DEBUGF(" add period:%u (%c%s)\n", (unsigned)td->curr_time, 371 DEBUGF(" add frame_period:%u (%c%s)\n", (unsigned)td->frame_time,
361 pic_coding_type_char(type), 372 pic_coding_type_char(type),
362 (td->info->display_picture->flags & PIC_FLAG_SKIP) ? 373 (td->info->display_picture->flags & PIC_FLAG_SKIP) ?
363 " skipped" : ""); 374 " skipped" : "");
364 } 375 }
365 376
366 td->period = TC_TO_TS(td->info->sequence->frame_period); 377 td->frame_period = TC_TO_TS(td->info->sequence->frame_period);
367 end_time = td->curr_time + td->period; 378 end_time = td->frame_time + td->frame_period;
368 379
369 DEBUGF(" ft:%u t:%u fe:%u (%c%s)", 380 DEBUGF(" ft:%u t:%u fe:%u (%c%s)",
370 (unsigned)td->curr_time, 381 (unsigned)td->frame_time,
371 (unsigned)time, 382 (unsigned)time,
372 (unsigned)end_time, 383 (unsigned)end_time,
373 pic_coding_type_char(type), 384 pic_coding_type_char(type),
@@ -383,12 +394,22 @@ static int sync_decoder(struct video_thread_data *td,
383 else if (!(td->info->display_picture->flags & PIC_FLAG_SKIP)) 394 else if (!(td->info->display_picture->flags & PIC_FLAG_SKIP))
384 { 395 {
385 /* One perfect point if dependent frames were decoded */ 396 /* One perfect point if dependent frames were decoded */
386 td->syncf_perfect = ipic; 397 switch (type)
387 398 {
388 if (type == PIC_FLAG_CODING_TYPE_B) 399 case PIC_FLAG_CODING_TYPE_B:
389 td->syncf_perfect &= ppic; 400 if (td->num_ref_pics > 1)
401 {
402 case PIC_FLAG_CODING_TYPE_P:
403 if (td->num_ref_pics > 0)
404 {
405 case PIC_FLAG_CODING_TYPE_I:
406 td->syncf_perfect = 1;
407 break;
408 }
409 }
410 }
390 411
391 if ((td->curr_time <= time && time < end_time) || 412 if ((td->frame_time <= time && time < end_time) ||
392 end_time >= video_str.end_pts) 413 end_time >= video_str.end_pts)
393 { 414 {
394 /* One perfect point for matching time goal */ 415 /* One perfect point for matching time goal */
@@ -464,20 +485,27 @@ static void video_thread_msg(struct video_thread_data *td)
464 485
465 switch (td->state) 486 switch (td->state)
466 { 487 {
488 case TSTATE_INIT:
489 /* Begin decoding state */
490 td->state = TSTATE_DECODE;
491 /* */
492 case TSTATE_DECODE:
493 if (td->syncf_perfect <= 0)
494 break;
495 /* There should be a frame already, just draw it */
496 td->goal_time = td->frame_time;
497 td->state = TSTATE_RENDER_WAIT;
498 /* */
467 case TSTATE_RENDER_WAIT: 499 case TSTATE_RENDER_WAIT:
468 /* Settings may have changed to nonlimited - just draw 500 /* Settings may have changed to nonlimited - just draw
469 * what was previously being waited for */ 501 * what was previously being waited for */
502 td->stream_time = TICKS_TO_TS(stream_get_time());
470 if (!settings.limitfps) 503 if (!settings.limitfps)
471 td->state = TSTATE_RENDER; 504 td->state = TSTATE_RENDER;
472 case TSTATE_DECODE: 505 /* */
473 case TSTATE_RENDER: 506 case TSTATE_RENDER:
474 break; 507 break;
475 508
476 case TSTATE_INIT:
477 /* Begin decoding state */
478 td->state = TSTATE_DECODE;
479 break;
480
481 case TSTATE_EOS: 509 case TSTATE_EOS:
482 /* At end of stream - no playback possible so fire the 510 /* At end of stream - no playback possible so fire the
483 * completion event */ 511 * completion event */
@@ -538,12 +566,14 @@ static void video_thread_msg(struct video_thread_data *td)
538 td->status = STREAM_STOPPED; 566 td->status = STREAM_STOPPED;
539 567
540 /* Reset operational info but not sync info */ 568 /* Reset operational info but not sync info */
541 td->eta_stream = UINT32_MAX; 569 td->stream_time = UINT32_MAX;
542 td->eta_video = 0; 570 td->goal_time = 0;
543 td->eta_early = 0; 571 td->remain_time = 0;
544 td->eta_late = 0; 572 td->skip_ref_pics = 0;
545 td->frame_drop_level = 0;
546 td->skip_level = 0; 573 td->skip_level = 0;
574 td->num_picture = 0;
575 td->num_intra = 0;
576 td->group_est = DEFAULT_GOP_SIZE;
547 td->last_render = *rb->current_tick - HZ; 577 td->last_render = *rb->current_tick - HZ;
548 video_num_drawn = 0; 578 video_num_drawn = 0;
549 video_num_skipped = 0; 579 video_num_skipped = 0;
@@ -639,13 +669,10 @@ static void video_thread(void)
639{ 669{
640 struct video_thread_data td; 670 struct video_thread_data td;
641 671
672 memset(&td, 0, sizeof (td));
673 td.mpeg2dec = mpeg2_init();
642 td.status = STREAM_STOPPED; 674 td.status = STREAM_STOPPED;
643 td.state = TSTATE_EOS; 675 td.state = TSTATE_EOS;
644 td.mpeg2dec = mpeg2_init();
645 td.info = NULL;
646 td.syncf_perfect = 0;
647 td.curr_time = 0;
648 td.period = 0;
649 676
650 if (td.mpeg2dec == NULL) 677 if (td.mpeg2dec == NULL)
651 { 678 {
@@ -687,10 +714,7 @@ static void video_thread(void)
687 case TSTATE_RENDER: goto picture_draw; 714 case TSTATE_RENDER: goto picture_draw;
688 case TSTATE_RENDER_WAIT: goto picture_wait; 715 case TSTATE_RENDER_WAIT: goto picture_wait;
689 /* Anything else is interpreted as an exit */ 716 /* Anything else is interpreted as an exit */
690 default: 717 default: goto video_exit;
691 vo_cleanup();
692 mpeg2_close(td.mpeg2dec);
693 return;
694 } 718 }
695 } 719 }
696 720
@@ -733,51 +757,72 @@ static void video_thread(void)
733 757
734 case STATE_PICTURE: 758 case STATE_PICTURE:
735 { 759 {
736 int skip = 0; /* Assume no skip */ 760 /* This is not in presentation order - do our best anyway */
761 int skip = td.skip_ref_pics;
737 762
738 if (td.frame_drop_level >= 1 || td.skip_level > 0) 763 /* Frame type: I/P/B/D */
764 switch (td.info->current_picture->flags & PIC_MASK_CODING_TYPE)
739 { 765 {
740 /* A frame will be dropped in the decoder */ 766 case PIC_FLAG_CODING_TYPE_I:
767 if (++td.num_intra >= 2)
768 td.group_est = td.num_picture / (td.num_intra - 1);
741 769
742 /* Frame type: I/P/B/D */ 770 /* Things are extremely late and all frames will be
743 int type = td.info->current_picture->flags 771 dropped until the next key frame */
744 & PIC_MASK_CODING_TYPE; 772 if (td.skip_level > 0 && td.skip_level >= td.group_est)
773 {
774 td.skip_level--; /* skip frame */
775 skip = td.skip_ref_pics = 1; /* wait for I-frame */
776 td.num_ref_pics = 0;
777 }
778 else if (skip != 0)
779 {
780 skip = td.skip_ref_pics = 0; /* now, decode */
781 td.num_ref_pics = 1;
782 }
783 break;
745 784
746 switch (type) 785 case PIC_FLAG_CODING_TYPE_P:
786 if (skip == 0)
747 { 787 {
748 case PIC_FLAG_CODING_TYPE_I: 788 td.num_ref_pics++;
749 case PIC_FLAG_CODING_TYPE_D: 789
750 /* Level 5: Things are extremely late and all frames will 790 /* If skip_level at least the estimated number of frames
751 be dropped until the next key frame */ 791 left in I-I span, skip until next I-frame */
752 if (td.frame_drop_level >= 1) 792 if (td.group_est > 0 && td.skip_level >= td.group_est)
753 td.frame_drop_level = 0; /* Key frame - reset drop level */
754 if (td.skip_level >= 5)
755 {
756 td.frame_drop_level = 1;
757 td.skip_level = 0; /* reset */
758 }
759 break;
760 case PIC_FLAG_CODING_TYPE_P:
761 /* Level 4: Things are very late and all frames will be
762 dropped until the next key frame */
763 if (td.skip_level >= 4)
764 { 793 {
765 td.frame_drop_level = 1; 794 skip = td.skip_ref_pics = 1; /* wait for I-frame */
766 td.skip_level = 0; /* reset */ 795 td.num_ref_pics = 0;
767 } 796 }
768 break; 797 }
769 case PIC_FLAG_CODING_TYPE_B: 798
770 /* We want to drop something, so this B frame won't even 799 if (skip != 0)
771 be decoded. Drawing can happen on the next frame if so 800 td.skip_level--;
772 desired. Bring the level down as skips are done. */ 801 break;
802
803 case PIC_FLAG_CODING_TYPE_B:
804 /* We want to drop something, so this B-frame won't even be
805 decoded. Drawing can happen on the next frame if so desired
806 so long as the B-frames were not dependent upon those from
807 a previous open GOP where the needed reference frames were
808 skipped */
809 if (td.skip_level > 0 || td.num_ref_pics < 2)
810 {
773 skip = 1; 811 skip = 1;
774 if (td.skip_level > 0) 812 td.skip_level--;
775 td.skip_level--;
776 } 813 }
814 break;
777 815
778 skip |= td.frame_drop_level; 816 default:
817 skip = 1;
818 break;
779 } 819 }
780 820
821 if (td.num_intra > 0)
822 td.num_picture++;
823
824 td.group_est--;
825
781 mpeg2_skip(td.mpeg2dec, skip); 826 mpeg2_skip(td.mpeg2dec, skip);
782 break; 827 break;
783 } 828 }
@@ -788,47 +833,73 @@ static void video_thread(void)
788 { 833 {
789 int32_t offset; /* Tick adjustment to keep sync */ 834 int32_t offset; /* Tick adjustment to keep sync */
790 835
791 /* draw current picture */
792 if (td.info->display_fbuf == NULL) 836 if (td.info->display_fbuf == NULL)
793 break; /* No picture */ 837 break; /* No picture */
794 838
795 td.syncf_perfect = 1; /* yes, a frame exists */
796
797 /* Get presentation times in audio samples - quite accurate 839 /* Get presentation times in audio samples - quite accurate
798 enough - add previous frame duration if not stamped */ 840 enough - add previous frame duration if not stamped */
799 td.curr_time = (td.info->display_picture->flags & PIC_FLAG_TAGS) ? 841 if (td.info->display_picture->flags & PIC_FLAG_TAGS)
800 td.info->display_picture->tag : (td.curr_time + td.period); 842 td.frame_time = td.info->display_picture->tag;
843 else
844 td.frame_time += td.frame_period;
801 845
802 td.period = TC_TO_TS(td.info->sequence->frame_period); 846 td.frame_period = TC_TO_TS(td.info->sequence->frame_period);
803 847
804 /* No limiting => no dropping - draw this frame */
805 if (!settings.limitfps) 848 if (!settings.limitfps)
806 { 849 {
850 /* No limiting => no dropping or waiting - draw this frame */
851 td.remain_time = 0;
852 td.skip_level = 0;
853 td.syncf_perfect = 1; /* have frame */
807 goto picture_draw; 854 goto picture_draw;
808 } 855 }
809 856
810 td.eta_video = td.curr_time; 857 td.goal_time = td.frame_time;
811 td.eta_stream = TICKS_TO_TS(stream_get_time()); 858 td.stream_time = TICKS_TO_TS(stream_get_time());
812 859
813 /* How early/late are we? > 0 = late, < 0 early */ 860 /* How early/late are we? > 0 = late, < 0 early */
814 offset = td.eta_stream - td.eta_video; 861 offset = td.stream_time - td.goal_time;
815 862
816 if (!settings.skipframes) 863 if (offset >= 0)
817 { 864 {
818 /* Make no effort to determine whether this frame should be 865 /* Late or on-time */
819 drawn or not since no action can be taken to correct the 866 if (td.remain_time < 0)
820 situation. We'll just wait if we're early and correct for 867 td.remain_time = 0; /* now, late */
821 lateness as much as possible. */ 868
822 if (offset < 0) 869 offset = AVERAGE(td.remain_time, offset, 4);
823 offset = 0; 870 td.remain_time = offset;
871 }
872 else
873 {
874 /* Early */
875 if (td.remain_time >= 0)
876 td.remain_time = 0; /* now, early */
877 else if (offset > td.remain_time)
878 td.remain_time = MAX(offset, -MAX_EARLINESS); /* less early */
879 else if (td.remain_time != 0)
880 td.remain_time = AVERAGE(td.remain_time, 0, 8); /* earlier/same */
881 /* else there's been no frame drop */
882
883 offset = -td.remain_time;
884 }
885
886 /* Skip anything not decoded */
887 if (td.info->display_picture->flags & PIC_FLAG_SKIP)
888 goto picture_skip;
824 889
825 td.eta_late = AVERAGE(td.eta_late, offset, 4); 890 td.syncf_perfect = 1; /* have frame (assume so from now on) */
826 offset = td.eta_late;
827 891
828 if ((uint32_t)offset > td.eta_video) 892 /* Keep goal_time >= 0 */
829 offset = td.eta_video; 893 if ((uint32_t)offset > td.goal_time)
894 offset = td.goal_time;
830 895
831 td.eta_video -= offset; 896 td.goal_time -= offset;
897
898 if (!settings.skipframes)
899 {
900 /* No skipping - just wait if we're early and correct for
901 lateness as much as possible. */
902 td.skip_level = 0;
832 goto picture_wait; 903 goto picture_wait;
833 } 904 }
834 905
@@ -838,112 +909,52 @@ static void video_thread(void)
838 * 909 *
839 * Frame Type Who Notes/Rationale 910 * Frame Type Who Notes/Rationale
840 * B decoder arbitrarily drop - no decode or draw 911 * B decoder arbitrarily drop - no decode or draw
841 * Any renderer arbitrarily drop - will be I/D/P 912 * Any renderer arbitrarily drop - I/P unless B decoded
842 * P decoder must wait for I/D-frame - choppy 913 * P decoder must wait for I-frame
843 * I/D decoder must wait for I/D-frame - choppy 914 * I decoder must wait for I-frame
844 * 915 *
845 * If a frame can be drawn and it has been at least 1/2 second, 916 * If a frame can be drawn and it has been at least 1/2 second,
846 * the image will be updated no matter how late it is just to 917 * the image will be updated no matter how late it is just to
847 * avoid looking stuck. 918 * avoid looking stuck.
848 */ 919 */
849 920 if (td.skip_level > 0 &&
850 /* If we're late, set the eta to play the frame early so
851 we may catch up. If early, especially because of a drop,
852 mitigate a "snap" by moving back gradually. */
853 if (offset >= 0) /* late or on time */
854 {
855 td.eta_early = 0; /* Not early now :( */
856
857 td.eta_late = AVERAGE(td.eta_late, offset, 4);
858 offset = td.eta_late;
859
860 if ((uint32_t)offset > td.eta_video)
861 offset = td.eta_video;
862
863 td.eta_video -= offset;
864 }
865 else
866 {
867 td.eta_late = 0; /* Not late now :) */
868
869 if (offset > td.eta_early)
870 {
871 /* Just dropped a frame and we're now early or we're
872 coming back from being early */
873 td.eta_early = offset;
874 if ((uint32_t)-offset > td.eta_video)
875 offset = -td.eta_video;
876
877 td.eta_video += offset;
878 }
879 else
880 {
881 /* Just early with an offset, do exponential drift back */
882 if (td.eta_early != 0)
883 {
884 td.eta_early = AVERAGE(td.eta_early, 0, 8);
885 td.eta_video = ((uint32_t)-td.eta_early > td.eta_video) ?
886 0 : (td.eta_video + td.eta_early);
887 }
888
889 offset = td.eta_early;
890 }
891 }
892
893 if (td.info->display_picture->flags & PIC_FLAG_SKIP)
894 {
895 /* This frame was set to skip so skip it after having updated
896 timing information */
897 td.eta_early = INT32_MIN;
898 video_num_skipped++;
899 goto picture_skip;
900 }
901
902 if (td.skip_level == 3 &&
903 TIME_BEFORE(*rb->current_tick, td.last_render + HZ/2)) 921 TIME_BEFORE(*rb->current_tick, td.last_render + HZ/2))
904 { 922 {
905 /* Render drop was set previously but nothing was dropped in the 923 /* Frame skip was set previously but either there wasn't anything
906 decoder or it's been to long since drawing the last frame. */ 924 dropped yet or not dropped enough. So we quit at least rendering
907 td.skip_level = 0; 925 the actual frame to avoid further increase of a/v-drift. */
908 td.eta_early = INT32_MIN; 926 td.skip_level--;
909 video_num_skipped++;
910 goto picture_skip; 927 goto picture_skip;
911 } 928 }
912 929
913 /* At this point a frame _will_ be drawn - a skip may happen on 930 /* At this point a frame _will_ be drawn - a skip may happen on
914 the next however */ 931 the next however */
915 td.skip_level = 0;
916 932
917 if (offset > TS_SECOND*110/1000) 933 /* Calculate number of frames to drop/skip - allow brief periods
934 of lateness before producing skips */
935 td.skip_level = 0;
936 if (td.remain_time > 0 && (uint32_t)offset > DROP_THRESHOLD)
918 { 937 {
919 /* Decide which skip level is needed in order to catch up */ 938 td.skip_level = (offset - DROP_THRESHOLD + td.frame_period)
920 939 / td.frame_period;
921 /* TODO: Calculate this rather than if...else - this is rather
922 exponential though */
923 if (offset > TS_SECOND*367/1000)
924 td.skip_level = 5; /* Decoder skip: I/D */
925 if (offset > TS_SECOND*233/1000)
926 td.skip_level = 4; /* Decoder skip: P */
927 else if (offset > TS_SECOND*167/1000)
928 td.skip_level = 3; /* Render skip */
929 else if (offset > TS_SECOND*133/1000)
930 td.skip_level = 2; /* Decoder skip: B */
931 else
932 td.skip_level = 1; /* Decoder skip: B */
933 } 940 }
934 941
935 picture_wait: 942 picture_wait:
936 td.state = TSTATE_RENDER_WAIT; 943 td.state = TSTATE_RENDER_WAIT;
937 944
938 /* Wait until time catches up */ 945 /* Wait until time catches up */
939 while (td.eta_video > td.eta_stream) 946 while (1)
940 { 947 {
948 int32_t twait = td.goal_time - td.stream_time;
941 /* Watch for messages while waiting for the frame time */ 949 /* Watch for messages while waiting for the frame time */
942 int32_t eta_remaining = td.eta_video - td.eta_stream; 950
943 if (eta_remaining > TS_SECOND/HZ) 951 if (twait <= 0)
952 break;
953
954 if (twait > TS_SECOND/HZ)
944 { 955 {
945 /* Several ticks to wait - do some sleeping */ 956 /* Several ticks to wait - do some sleeping */
946 int timeout = (eta_remaining - HZ) / (TS_SECOND/HZ); 957 int timeout = (twait - HZ) / (TS_SECOND/HZ);
947 str_get_msg_w_tmo(&video_str, &td.ev, MAX(timeout, 1)); 958 str_get_msg_w_tmo(&video_str, &td.ev, MAX(timeout, 1));
948 if (td.ev.id != SYS_TIMEOUT) 959 if (td.ev.id != SYS_TIMEOUT)
949 goto message_process; 960 goto message_process;
@@ -956,7 +967,7 @@ static void video_thread(void)
956 goto message_wait; 967 goto message_wait;
957 } 968 }
958 969
959 td.eta_stream = TICKS_TO_TS(stream_get_time()); 970 td.stream_time = TICKS_TO_TS(stream_get_time());
960 } 971 }
961 972
962 picture_draw: 973 picture_draw:
@@ -965,8 +976,17 @@ static void video_thread(void)
965 976
966 vo_draw_frame(td.info->display_fbuf->buf); 977 vo_draw_frame(td.info->display_fbuf->buf);
967 video_num_drawn++; 978 video_num_drawn++;
979 break;
968 980
969 picture_skip: 981 picture_skip:
982 if (td.remain_time <= DROP_THRESHOLD)
983 {
984 td.skip_level = 0;
985 if (td.remain_time <= 0)
986 td.remain_time = INT32_MIN;
987 }
988
989 video_num_skipped++;
970 break; 990 break;
971 } 991 }
972 992
@@ -976,6 +996,10 @@ static void video_thread(void)
976 996
977 rb->yield(); 997 rb->yield();
978 } /* end while */ 998 } /* end while */
999
1000video_exit:
1001 vo_cleanup();
1002 mpeg2_close(td.mpeg2dec);
979} 1003}
980 1004
981/* Initializes the video thread */ 1005/* Initializes the video thread */