diff options
Diffstat (limited to 'apps/plugins/mpegplayer/video_thread.c')
-rw-r--r-- | apps/plugins/mpegplayer/video_thread.c | 76 |
1 files changed, 34 insertions, 42 deletions
diff --git a/apps/plugins/mpegplayer/video_thread.c b/apps/plugins/mpegplayer/video_thread.c index 950d49a935..6a54706942 100644 --- a/apps/plugins/mpegplayer/video_thread.c +++ b/apps/plugins/mpegplayer/video_thread.c | |||
@@ -37,8 +37,6 @@ struct video_thread_data | |||
37 | struct queue_event ev; /* Our event queue to receive commands */ | 37 | struct queue_event ev; /* Our event queue to receive commands */ |
38 | int num_drawn; /* Number of frames drawn since reset */ | 38 | int num_drawn; /* Number of frames drawn since reset */ |
39 | int num_skipped; /* Number of frames skipped since reset */ | 39 | int num_skipped; /* Number of frames skipped since reset */ |
40 | uint32_t curr_time; /* Current due time of frame */ | ||
41 | uint32_t period; /* Frame period in clock ticks */ | ||
42 | uint32_t eta_stream; /* Current time of stream */ | 40 | uint32_t eta_stream; /* Current time of stream */ |
43 | uint32_t eta_video; /* Time that frame has been scheduled for */ | 41 | uint32_t eta_video; /* Time that frame has been scheduled for */ |
44 | int32_t eta_early; /* How early has the frame been decoded? */ | 42 | int32_t eta_early; /* How early has the frame been decoded? */ |
@@ -47,9 +45,9 @@ struct video_thread_data | |||
47 | int skip_level; /* Skip severity */ | 45 | int skip_level; /* Skip severity */ |
48 | long last_showfps; /* Last time the FPS display was updated */ | 46 | long last_showfps; /* Last time the FPS display was updated */ |
49 | long last_render; /* Last time a frame was drawn */ | 47 | long last_render; /* Last time a frame was drawn */ |
48 | uint32_t curr_time; /* Current due time of frame */ | ||
49 | uint32_t period; /* Frame period in clock ticks */ | ||
50 | int syncf_perfect; /* Last sync fit result */ | 50 | int syncf_perfect; /* Last sync fit result */ |
51 | uint32_t syncf_time; /* PTS of last synced frame */ | ||
52 | uint32_t syncf_period; /* TS duration of last synced frame */ | ||
53 | }; | 51 | }; |
54 | 52 | ||
55 | /* TODO: Check if 4KB is appropriate - it works for my test streams, | 53 | /* TODO: Check if 4KB is appropriate - it works for my test streams, |
@@ -221,7 +219,7 @@ static bool init_sequence(struct video_thread_data *td) | |||
221 | 219 | ||
222 | static bool check_needs_sync(struct video_thread_data *td, uint32_t time) | 220 | static bool check_needs_sync(struct video_thread_data *td, uint32_t time) |
223 | { | 221 | { |
224 | uint32_t syncf_end; | 222 | uint32_t end_time; |
225 | 223 | ||
226 | DEBUGF("check_needs_sync:\n"); | 224 | DEBUGF("check_needs_sync:\n"); |
227 | if (td->info == NULL || td->info->display_fbuf == NULL) | 225 | if (td->info == NULL || td->info->display_fbuf == NULL) |
@@ -237,16 +235,16 @@ static bool check_needs_sync(struct video_thread_data *td, uint32_t time) | |||
237 | } | 235 | } |
238 | 236 | ||
239 | time = clip_time(&video_str, time); | 237 | time = clip_time(&video_str, time); |
240 | syncf_end = td->syncf_time + td->syncf_period; | 238 | end_time = td->curr_time + td->period; |
241 | 239 | ||
242 | DEBUGF(" sft:%u t:%u sfte:%u\n", (unsigned)td->syncf_time, | 240 | DEBUGF(" sft:%u t:%u sfte:%u\n", (unsigned)td->curr_time, |
243 | (unsigned)time, (unsigned)syncf_end); | 241 | (unsigned)time, (unsigned)end_time); |
244 | 242 | ||
245 | if (time < td->syncf_time) | 243 | if (time < td->curr_time) |
246 | return true; | 244 | return true; |
247 | 245 | ||
248 | if (time >= syncf_end) | 246 | if (time >= end_time) |
249 | return time < video_str.end_pts || syncf_end < video_str.end_pts; | 247 | return time < video_str.end_pts || end_time < video_str.end_pts; |
250 | 248 | ||
251 | return false; | 249 | return false; |
252 | } | 250 | } |
@@ -260,8 +258,6 @@ static int sync_decoder(struct video_thread_data *td, | |||
260 | uint32_t time = clip_time(&video_str, sd->time); | 258 | uint32_t time = clip_time(&video_str, sd->time); |
261 | 259 | ||
262 | td->syncf_perfect = 0; | 260 | td->syncf_perfect = 0; |
263 | td->syncf_time = 0; | ||
264 | td->syncf_period = 0; | ||
265 | td->curr_time = 0; | 261 | td->curr_time = 0; |
266 | td->period = 0; | 262 | td->period = 0; |
267 | 263 | ||
@@ -358,7 +354,7 @@ static int sync_decoder(struct video_thread_data *td, | |||
358 | case STATE_END: | 354 | case STATE_END: |
359 | case STATE_INVALID_END: | 355 | case STATE_INVALID_END: |
360 | { | 356 | { |
361 | uint32_t syncf_end; | 357 | uint32_t end_time; |
362 | 358 | ||
363 | if (td->info->display_picture == NULL) | 359 | if (td->info->display_picture == NULL) |
364 | { | 360 | { |
@@ -371,36 +367,33 @@ static int sync_decoder(struct video_thread_data *td, | |||
371 | 367 | ||
372 | if (td->info->display_picture->flags & PIC_FLAG_TAGS) | 368 | if (td->info->display_picture->flags & PIC_FLAG_TAGS) |
373 | { | 369 | { |
374 | td->syncf_time = td->info->display_picture->tag; | 370 | td->curr_time = td->info->display_picture->tag; |
375 | DEBUGF(" frame tagged:%u (%c%s)\n", (unsigned)td->syncf_time, | 371 | DEBUGF(" frame tagged:%u (%c%s)\n", (unsigned)td->curr_time, |
376 | pic_coding_type_char(type), | 372 | pic_coding_type_char(type), |
377 | (td->info->display_picture->flags & PIC_FLAG_SKIP) ? | 373 | (td->info->display_picture->flags & PIC_FLAG_SKIP) ? |
378 | " skipped" : ""); | 374 | " skipped" : ""); |
379 | } | 375 | } |
380 | else | 376 | else |
381 | { | 377 | { |
382 | td->syncf_time += td->syncf_period; | 378 | td->curr_time += td->period; |
383 | DEBUGF(" add period:%u (%c%s)\n", (unsigned)td->syncf_time, | 379 | DEBUGF(" add period:%u (%c%s)\n", (unsigned)td->curr_time, |
384 | pic_coding_type_char(type), | 380 | pic_coding_type_char(type), |
385 | (td->info->display_picture->flags & PIC_FLAG_SKIP) ? | 381 | (td->info->display_picture->flags & PIC_FLAG_SKIP) ? |
386 | " skipped" : ""); | 382 | " skipped" : ""); |
387 | } | 383 | } |
388 | 384 | ||
389 | td->syncf_period = TC_TO_TS(td->info->sequence->frame_period); | 385 | td->period = TC_TO_TS(td->info->sequence->frame_period); |
390 | syncf_end = td->syncf_time + td->syncf_period; | 386 | end_time = td->curr_time + td->period; |
391 | 387 | ||
392 | DEBUGF(" ft:%u t:%u fe:%u (%c%s)", | 388 | DEBUGF(" ft:%u t:%u fe:%u (%c%s)", |
393 | (unsigned)td->syncf_time, | 389 | (unsigned)td->curr_time, |
394 | (unsigned)time, | 390 | (unsigned)time, |
395 | (unsigned)(td->syncf_time + td->syncf_period), | 391 | (unsigned)end_time, |
396 | pic_coding_type_char(type), | 392 | pic_coding_type_char(type), |
397 | (td->info->display_picture->flags & PIC_FLAG_SKIP) ? | 393 | (td->info->display_picture->flags & PIC_FLAG_SKIP) ? |
398 | " skipped" : ""); | 394 | " skipped" : ""); |
399 | 395 | ||
400 | td->curr_time = TS_TO_TICKS(td->syncf_time); | 396 | if (end_time <= time && end_time < video_str.end_pts) |
401 | td->period = TS_TO_TICKS(td->syncf_period); | ||
402 | |||
403 | if (syncf_end <= time && syncf_end < video_str.end_pts) | ||
404 | { | 397 | { |
405 | /* Still too early and have not hit at EOS */ | 398 | /* Still too early and have not hit at EOS */ |
406 | DEBUGF(" too early\n"); | 399 | DEBUGF(" too early\n"); |
@@ -414,8 +407,8 @@ static int sync_decoder(struct video_thread_data *td, | |||
414 | if (type == PIC_FLAG_CODING_TYPE_B) | 407 | if (type == PIC_FLAG_CODING_TYPE_B) |
415 | td->syncf_perfect &= ppic; | 408 | td->syncf_perfect &= ppic; |
416 | 409 | ||
417 | if ((td->syncf_time <= time && time < syncf_end) || | 410 | if ((td->curr_time <= time && time < end_time) || |
418 | syncf_end >= video_str.end_pts) | 411 | end_time >= video_str.end_pts) |
419 | { | 412 | { |
420 | /* One perfect point for matching time goal */ | 413 | /* One perfect point for matching time goal */ |
421 | DEBUGF(" ft<=t<fe\n"); | 414 | DEBUGF(" ft<=t<fe\n"); |
@@ -662,8 +655,8 @@ static void video_thread(void) | |||
662 | td.mpeg2dec = mpeg2_init(); | 655 | td.mpeg2dec = mpeg2_init(); |
663 | td.info = NULL; | 656 | td.info = NULL; |
664 | td.syncf_perfect = 0; | 657 | td.syncf_perfect = 0; |
665 | td.syncf_time = 0; | 658 | td.curr_time = 0; |
666 | td.syncf_period = 0; | 659 | td.period = 0; |
667 | 660 | ||
668 | if (td.mpeg2dec == NULL) | 661 | if (td.mpeg2dec == NULL) |
669 | { | 662 | { |
@@ -814,10 +807,9 @@ static void video_thread(void) | |||
814 | /* Get presentation times in audio samples - quite accurate | 807 | /* Get presentation times in audio samples - quite accurate |
815 | enough - add previous frame duration if not stamped */ | 808 | enough - add previous frame duration if not stamped */ |
816 | td.curr_time = (td.info->display_picture->flags & PIC_FLAG_TAGS) ? | 809 | td.curr_time = (td.info->display_picture->flags & PIC_FLAG_TAGS) ? |
817 | TS_TO_TICKS(td.info->display_picture->tag) : | 810 | td.info->display_picture->tag : (td.curr_time + td.period); |
818 | (td.curr_time + td.period); | ||
819 | 811 | ||
820 | td.period = TC_TO_TICKS(td.info->sequence->frame_period); | 812 | td.period = TC_TO_TS(td.info->sequence->frame_period); |
821 | 813 | ||
822 | /* No limiting => no dropping - draw this frame */ | 814 | /* No limiting => no dropping - draw this frame */ |
823 | if (!settings.limitfps) | 815 | if (!settings.limitfps) |
@@ -826,7 +818,7 @@ static void video_thread(void) | |||
826 | } | 818 | } |
827 | 819 | ||
828 | td.eta_video = td.curr_time; | 820 | td.eta_video = td.curr_time; |
829 | td.eta_stream = stream_get_time(); | 821 | td.eta_stream = TICKS_TO_TS(stream_get_time()); |
830 | 822 | ||
831 | /* How early/late are we? > 0 = late, < 0 early */ | 823 | /* How early/late are we? > 0 = late, < 0 early */ |
832 | offset = td.eta_stream - td.eta_video; | 824 | offset = td.eta_stream - td.eta_video; |
@@ -932,19 +924,19 @@ static void video_thread(void) | |||
932 | the next however */ | 924 | the next however */ |
933 | td.skip_level = 0; | 925 | td.skip_level = 0; |
934 | 926 | ||
935 | if (offset > CLOCK_RATE*110/1000) | 927 | if (offset > TS_SECOND*110/1000) |
936 | { | 928 | { |
937 | /* Decide which skip level is needed in order to catch up */ | 929 | /* Decide which skip level is needed in order to catch up */ |
938 | 930 | ||
939 | /* TODO: Calculate this rather than if...else - this is rather | 931 | /* TODO: Calculate this rather than if...else - this is rather |
940 | exponential though */ | 932 | exponential though */ |
941 | if (offset > CLOCK_RATE*367/1000) | 933 | if (offset > TS_SECOND*367/1000) |
942 | td.skip_level = 5; /* Decoder skip: I/D */ | 934 | td.skip_level = 5; /* Decoder skip: I/D */ |
943 | if (offset > CLOCK_RATE*233/1000) | 935 | if (offset > TS_SECOND*233/1000) |
944 | td.skip_level = 4; /* Decoder skip: P */ | 936 | td.skip_level = 4; /* Decoder skip: P */ |
945 | else if (offset > CLOCK_RATE*167/1000) | 937 | else if (offset > TS_SECOND*167/1000) |
946 | td.skip_level = 3; /* Render skip */ | 938 | td.skip_level = 3; /* Render skip */ |
947 | else if (offset > CLOCK_RATE*133/1000) | 939 | else if (offset > TS_SECOND*133/1000) |
948 | td.skip_level = 2; /* Decoder skip: B */ | 940 | td.skip_level = 2; /* Decoder skip: B */ |
949 | else | 941 | else |
950 | td.skip_level = 1; /* Decoder skip: B */ | 942 | td.skip_level = 1; /* Decoder skip: B */ |
@@ -958,10 +950,10 @@ static void video_thread(void) | |||
958 | { | 950 | { |
959 | /* Watch for messages while waiting for the frame time */ | 951 | /* Watch for messages while waiting for the frame time */ |
960 | int32_t eta_remaining = td.eta_video - td.eta_stream; | 952 | int32_t eta_remaining = td.eta_video - td.eta_stream; |
961 | if (eta_remaining > CLOCK_RATE/HZ) | 953 | if (eta_remaining > TS_SECOND/HZ) |
962 | { | 954 | { |
963 | /* Several ticks to wait - do some sleeping */ | 955 | /* Several ticks to wait - do some sleeping */ |
964 | int timeout = (eta_remaining - HZ) / (CLOCK_RATE/HZ); | 956 | int timeout = (eta_remaining - HZ) / (TS_SECOND/HZ); |
965 | str_get_msg_w_tmo(&video_str, &td.ev, MAX(timeout, 1)); | 957 | str_get_msg_w_tmo(&video_str, &td.ev, MAX(timeout, 1)); |
966 | if (td.ev.id != SYS_TIMEOUT) | 958 | if (td.ev.id != SYS_TIMEOUT) |
967 | goto message_process; | 959 | goto message_process; |
@@ -974,7 +966,7 @@ static void video_thread(void) | |||
974 | goto message_wait; | 966 | goto message_wait; |
975 | } | 967 | } |
976 | 968 | ||
977 | td.eta_stream = stream_get_time(); | 969 | td.eta_stream = TICKS_TO_TS(stream_get_time()); |
978 | } | 970 | } |
979 | 971 | ||
980 | picture_draw: | 972 | picture_draw: |