diff options
Diffstat (limited to 'apps/plugins')
-rw-r--r-- | apps/plugins/mpegplayer/mpegplayer.c | 211 |
1 files changed, 119 insertions, 92 deletions
diff --git a/apps/plugins/mpegplayer/mpegplayer.c b/apps/plugins/mpegplayer/mpegplayer.c index 7d97766c35..b4b3281225 100644 --- a/apps/plugins/mpegplayer/mpegplayer.c +++ b/apps/plugins/mpegplayer/mpegplayer.c | |||
@@ -108,10 +108,6 @@ FPS | 27Mhz | 100Hz | 44.1KHz | 48KHz | |||
108 | #include "mpeg2.h" | 108 | #include "mpeg2.h" |
109 | #include "mpeg_settings.h" | 109 | #include "mpeg_settings.h" |
110 | #include "video_out.h" | 110 | #include "video_out.h" |
111 | #ifndef ATTR_ALIGN | ||
112 | #define ATTR_ALIGN(a) __attribute__((aligned (a))) | ||
113 | #endif | ||
114 | #include "mpeg2_internal.h" | ||
115 | #include "../../codecs/libmad/mad.h" | 111 | #include "../../codecs/libmad/mad.h" |
116 | 112 | ||
117 | PLUGIN_HEADER | 113 | PLUGIN_HEADER |
@@ -493,12 +489,13 @@ static void init_mad(void* mad_frame_overlap) | |||
493 | #define SYSTEM_HEADER_START_CODE 0x000001bbul | 489 | #define SYSTEM_HEADER_START_CODE 0x000001bbul |
494 | 490 | ||
495 | /* p = base pointer, b0 - b4 = byte offsets from p */ | 491 | /* p = base pointer, b0 - b4 = byte offsets from p */ |
492 | /* We only care about the MS 32 bits of the 33 and so the ticks are 45kHz */ | ||
496 | #define TS_FROM_HEADER(p, b0, b1, b2, b3, b4) \ | 493 | #define TS_FROM_HEADER(p, b0, b1, b2, b3, b4) \ |
497 | ((uint32_t)(((p)[b0] >> 1 << 30) | \ | 494 | ((uint32_t)(((p)[b0] >> 1 << 29) | \ |
498 | ((p)[b1] << 22) | \ | 495 | ((p)[b1] << 21) | \ |
499 | ((p)[b2] >> 1 << 15) | \ | 496 | ((p)[b2] >> 1 << 14) | \ |
500 | ((p)[b3] << 7) | \ | 497 | ((p)[b3] << 6) | \ |
501 | ((p)[b4] >> 1 ))) | 498 | ((p)[b4] >> 2 ))) |
502 | 499 | ||
503 | /* This function demuxes the streams and gives the next stream data pointer */ | 500 | /* This function demuxes the streams and gives the next stream data pointer */ |
504 | static void get_next_data( Stream* str ) | 501 | static void get_next_data( Stream* str ) |
@@ -612,10 +609,12 @@ static void get_next_data( Stream* str ) | |||
612 | /* header points to the mpeg2 pes header */ | 609 | /* header points to the mpeg2 pes header */ |
613 | if (header[7] & 0x80) | 610 | if (header[7] & 0x80) |
614 | { | 611 | { |
612 | /* header has a pts */ | ||
615 | uint32_t pts = TS_FROM_HEADER(header, 9, 10, 11, 12, 13); | 613 | uint32_t pts = TS_FROM_HEADER(header, 9, 10, 11, 12, 13); |
616 | 614 | ||
617 | if (stream >= 0xe0) | 615 | if (stream >= 0xe0) |
618 | { | 616 | { |
617 | /* video stream - header may have a dts as well */ | ||
619 | uint32_t dts = (header[7] & 0x40) == 0 ? | 618 | uint32_t dts = (header[7] & 0x40) == 0 ? |
620 | pts : TS_FROM_HEADER(header, 14, 15, 16, 17, 18); | 619 | pts : TS_FROM_HEADER(header, 14, 15, 16, 17, 18); |
621 | 620 | ||
@@ -659,10 +658,12 @@ static void get_next_data( Stream* str ) | |||
659 | 658 | ||
660 | if ((ptsbuf[-1] & 0xe0) == 0x20) | 659 | if ((ptsbuf[-1] & 0xe0) == 0x20) |
661 | { | 660 | { |
661 | /* header has a pts */ | ||
662 | uint32_t pts = TS_FROM_HEADER(ptsbuf, -1, 0, 1, 2, 3); | 662 | uint32_t pts = TS_FROM_HEADER(ptsbuf, -1, 0, 1, 2, 3); |
663 | 663 | ||
664 | if (stream >= 0xe0) | 664 | if (stream >= 0xe0) |
665 | { | 665 | { |
666 | /* video stream - header may have a dts as well */ | ||
666 | uint32_t dts = (ptsbuf[-1] & 0xf0) != 0x30 ? | 667 | uint32_t dts = (ptsbuf[-1] & 0xf0) != 0x30 ? |
667 | pts : TS_FROM_HEADER(ptsbuf, 4, 5, 6, 7, 18); | 668 | pts : TS_FROM_HEADER(ptsbuf, 4, 5, 6, 7, 18); |
668 | 669 | ||
@@ -723,8 +724,8 @@ static void get_next_data( Stream* str ) | |||
723 | 724 | ||
724 | /* For simple lowpass filtering of sync variables */ | 725 | /* For simple lowpass filtering of sync variables */ |
725 | #define AVERAGE(var, x, count) (((var) * (count-1) + (x)) / (count)) | 726 | #define AVERAGE(var, x, count) (((var) * (count-1) + (x)) / (count)) |
726 | /* Convert 90kHz PTS/DTS ticks to our clock ticks */ | 727 | /* Convert 45kHz PTS/DTS ticks to our clock ticks */ |
727 | #define TS_TO_TICKS(pts) ((uint64_t)CLOCK_RATE*(pts) / 90000) | 728 | #define TS_TO_TICKS(pts) ((uint64_t)CLOCK_RATE*(pts) / 45000) |
728 | /* Convert 27MHz ticks to our clock ticks */ | 729 | /* Convert 27MHz ticks to our clock ticks */ |
729 | #define TIME_TO_TICKS(stamp) ((uint64_t)CLOCK_RATE*(stamp) / 27000000) | 730 | #define TIME_TO_TICKS(stamp) ((uint64_t)CLOCK_RATE*(stamp) / 27000000) |
730 | 731 | ||
@@ -737,14 +738,14 @@ static bool init_mpabuf(void) | |||
737 | return mpa_buffer != NULL; | 738 | return mpa_buffer != NULL; |
738 | } | 739 | } |
739 | 740 | ||
740 | #define PTS_QUEUE_LEN (1 << 4) /* 16 should be way more than sufficient - | 741 | #define PTS_QUEUE_LEN (1 << 5) /* 32 should be way more than sufficient - |
741 | if not, the case is handled */ | 742 | if not, the case is handled */ |
742 | #define PTS_QUEUE_MASK (PTS_QUEUE_LEN-1) | 743 | #define PTS_QUEUE_MASK (PTS_QUEUE_LEN-1) |
743 | struct pts_queue_slot | 744 | struct pts_queue_slot |
744 | { | 745 | { |
745 | uint32_t pts; /* Time stamp for packet */ | 746 | uint32_t pts; /* Time stamp for packet */ |
746 | ssize_t size; /* Number of bytes left in packet */ | 747 | ssize_t size; /* Number of bytes left in packet */ |
747 | } pts_queue[PTS_QUEUE_MASK+1]; | 748 | } pts_queue[PTS_QUEUE_LEN]; |
748 | 749 | ||
749 | /* This starts out wr == rd but will never be emptied to zero during | 750 | /* This starts out wr == rd but will never be emptied to zero during |
750 | streaming again in order to support initializing the first packet's | 751 | streaming again in order to support initializing the first packet's |
@@ -752,12 +753,6 @@ struct pts_queue_slot | |||
752 | static unsigned pts_queue_rd; | 753 | static unsigned pts_queue_rd; |
753 | static unsigned pts_queue_wr; | 754 | static unsigned pts_queue_wr; |
754 | 755 | ||
755 | /* Resets the pts queue - call when starting and seeking */ | ||
756 | static void pts_queue_reset(void) | ||
757 | { | ||
758 | pts_queue_rd = pts_queue_wr; | ||
759 | } | ||
760 | |||
761 | /* Increments the queue head postion - should be used to preincrement */ | 756 | /* Increments the queue head postion - should be used to preincrement */ |
762 | static bool pts_queue_add_head(void) | 757 | static bool pts_queue_add_head(void) |
763 | { | 758 | { |
@@ -790,6 +785,16 @@ static struct pts_queue_slot * pts_queue_tail(void) | |||
790 | return &pts_queue[pts_queue_rd & PTS_QUEUE_MASK]; | 785 | return &pts_queue[pts_queue_rd & PTS_QUEUE_MASK]; |
791 | } | 786 | } |
792 | 787 | ||
788 | /* Resets the pts queue - call when starting and seeking */ | ||
789 | static void pts_queue_reset(void) | ||
790 | { | ||
791 | struct pts_queue_slot *pts; | ||
792 | pts_queue_rd = pts_queue_wr; | ||
793 | pts = pts_queue_tail(); | ||
794 | pts->pts = 0; | ||
795 | pts->size = 0; | ||
796 | } | ||
797 | |||
793 | struct pcm_frame_header /* Header added to pcm data every time a decoded | 798 | struct pcm_frame_header /* Header added to pcm data every time a decoded |
794 | mpa frame is sent out */ | 799 | mpa frame is sent out */ |
795 | { | 800 | { |
@@ -992,6 +997,21 @@ static void audio_thread(void) | |||
992 | if (audiostatus == PLEASE_STOP) | 997 | if (audiostatus == PLEASE_STOP) |
993 | goto done; | 998 | goto done; |
994 | 999 | ||
1000 | if (pts->size <= 0) | ||
1001 | { | ||
1002 | /* Carry any overshoot to the next size since we're technically | ||
1003 | -pts->size bytes into it already. If size is negative an audio | ||
1004 | frame was split accross packets. Old has to be saved before | ||
1005 | moving the tail. */ | ||
1006 | if (pts_queue_remove_tail()) | ||
1007 | { | ||
1008 | struct pts_queue_slot *old = pts; | ||
1009 | pts = pts_queue_tail(); | ||
1010 | pts->size += old->size; | ||
1011 | old->size = 0; | ||
1012 | } | ||
1013 | } | ||
1014 | |||
995 | /** Buffering **/ | 1015 | /** Buffering **/ |
996 | if (mpabuf_used >= MPA_MAX_FRAME_SIZE + MAD_BUFFER_GUARD) | 1016 | if (mpabuf_used >= MPA_MAX_FRAME_SIZE + MAD_BUFFER_GUARD) |
997 | { | 1017 | { |
@@ -999,46 +1019,53 @@ static void audio_thread(void) | |||
999 | } | 1019 | } |
1000 | else if (audio_str.curr_packet != NULL) | 1020 | else if (audio_str.curr_packet != NULL) |
1001 | { | 1021 | { |
1002 | /* Get data from next audio packet */ | 1022 | do |
1003 | len = audio_str.curr_packet_end - audio_str.curr_packet; | ||
1004 | |||
1005 | if (audio_str.tagged) | ||
1006 | { | 1023 | { |
1007 | struct pts_queue_slot *stamp = pts; | 1024 | /* Get data from next audio packet */ |
1025 | len = audio_str.curr_packet_end - audio_str.curr_packet; | ||
1026 | |||
1027 | if (audio_str.tagged) | ||
1028 | { | ||
1029 | struct pts_queue_slot *stamp = pts; | ||
1008 | 1030 | ||
1009 | if (pts_queue_add_head()) | 1031 | if (pts_queue_add_head()) |
1032 | { | ||
1033 | stamp = pts_queue_head(); | ||
1034 | stamp->pts = TS_TO_TICKS(audio_str.curr_pts); | ||
1035 | /* pts->size should have been zeroed when slot was | ||
1036 | freed */ | ||
1037 | } | ||
1038 | /* else queue full - just count up from the last to make | ||
1039 | it look like more data in the same packet */ | ||
1040 | stamp->size += len; | ||
1041 | audio_str.tagged = 0; | ||
1042 | } | ||
1043 | else | ||
1010 | { | 1044 | { |
1011 | stamp = pts_queue_head(); | 1045 | /* Add to the one just behind the head - this may be the |
1012 | stamp->pts = TS_TO_TICKS(audio_str.curr_pts); | 1046 | tail or the previouly added head - whether or not we'll |
1013 | /* pts->size should have been zeroed when slot was freed */ | 1047 | ever reach this is quite in question since audio always |
1048 | seems to have every packet timestamped */ | ||
1049 | pts_queue_head()->size += len; | ||
1014 | } | 1050 | } |
1015 | /* else queue full - just count up from the last to make it look | ||
1016 | like more data in the same packet */ | ||
1017 | stamp->size += len; | ||
1018 | audio_str.tagged = 0; | ||
1019 | } | ||
1020 | else | ||
1021 | { | ||
1022 | /* Add to the one just behind the head - this may be the tail or | ||
1023 | the previouly added head - whether or not we'll ever reach this | ||
1024 | is quite in question since audio always seems to have every | ||
1025 | packet timestamped */ | ||
1026 | pts_queue_head()->size += len; | ||
1027 | } | ||
1028 | 1051 | ||
1029 | /* Slide any remainder over to beginning - avoid function call overhead if | 1052 | /* Slide any remainder over to beginning - avoid function |
1030 | no data remaining as well */ | 1053 | call overhead if no data remaining as well */ |
1031 | if (mpabuf > mpa_buffer && mpabuf_used > 0) | 1054 | if (mpabuf > mpa_buffer && mpabuf_used > 0) |
1032 | rb->memmove(mpa_buffer, mpabuf, mpabuf_used); | 1055 | rb->memmove(mpa_buffer, mpabuf, mpabuf_used); |
1033 | 1056 | ||
1034 | /* Splice this packet onto any remainder */ | 1057 | /* Splice this packet onto any remainder */ |
1035 | rb->memcpy(mpa_buffer + mpabuf_used, audio_str.curr_packet, len); | 1058 | rb->memcpy(mpa_buffer + mpabuf_used, audio_str.curr_packet, |
1059 | len); | ||
1036 | 1060 | ||
1037 | mpabuf_used += len; | 1061 | mpabuf_used += len; |
1038 | mpabuf = mpa_buffer; | 1062 | mpabuf = mpa_buffer; |
1039 | 1063 | ||
1040 | /* Move stream position to the next packet */ | 1064 | /* Get data from next audio packet */ |
1041 | get_next_data(&audio_str); | 1065 | get_next_data(&audio_str); |
1066 | } | ||
1067 | while (audio_str.curr_packet != NULL && | ||
1068 | mpabuf_used < MPA_MAX_FRAME_SIZE + MAD_BUFFER_GUARD); | ||
1042 | } | 1069 | } |
1043 | else if (mpabuf_used <= 0) | 1070 | else if (mpabuf_used <= 0) |
1044 | { | 1071 | { |
@@ -1051,6 +1078,13 @@ static void audio_thread(void) | |||
1051 | 1078 | ||
1052 | mad_stat = mad_frame_decode(&frame, &stream); | 1079 | mad_stat = mad_frame_decode(&frame, &stream); |
1053 | 1080 | ||
1081 | if (stream.next_frame == NULL) | ||
1082 | { | ||
1083 | /* What to do here? (This really is fatal) */ | ||
1084 | DEBUGF("/* What to do here? */\n"); | ||
1085 | break; | ||
1086 | } | ||
1087 | |||
1054 | /* Next mad stream buffer is the next frame postion */ | 1088 | /* Next mad stream buffer is the next frame postion */ |
1055 | mpabuf = (uint8_t *)stream.next_frame; | 1089 | mpabuf = (uint8_t *)stream.next_frame; |
1056 | 1090 | ||
@@ -1059,25 +1093,6 @@ static void audio_thread(void) | |||
1059 | mpabuf_used -= len; | 1093 | mpabuf_used -= len; |
1060 | pts->size -= len; | 1094 | pts->size -= len; |
1061 | 1095 | ||
1062 | if (pts->size <= 0) | ||
1063 | { | ||
1064 | /* Carry any overshoot to the next size since we're technically | ||
1065 | -pts->size bytes into it already. If size is negative an audio | ||
1066 | frame was split accross packets. Old has to be saved before | ||
1067 | moving the tail. */ | ||
1068 | struct pts_queue_slot *old = pts; | ||
1069 | |||
1070 | if (pts_queue_remove_tail()) | ||
1071 | { | ||
1072 | pts = pts_queue_tail(); | ||
1073 | pts->size += old->size; | ||
1074 | } | ||
1075 | |||
1076 | /* Zero the size of the last slot to simplify stamping code and ensure | ||
1077 | that it is never negative if the tail didn't move */ | ||
1078 | old->size = 0; | ||
1079 | } | ||
1080 | |||
1081 | if (mad_stat != 0) | 1096 | if (mad_stat != 0) |
1082 | { | 1097 | { |
1083 | DEBUGF("Audio stream error - %d\n", stream.error); | 1098 | DEBUGF("Audio stream error - %d\n", stream.error); |
@@ -1113,13 +1128,6 @@ static void audio_thread(void) | |||
1113 | /* Generate the pcm samples */ | 1128 | /* Generate the pcm samples */ |
1114 | mad_synth_frame(&synth, &frame); | 1129 | mad_synth_frame(&synth, &frame); |
1115 | 1130 | ||
1116 | if (stream.next_frame == NULL) | ||
1117 | { | ||
1118 | /* What to do here? */ | ||
1119 | DEBUGF("/* What to do here? */\n"); | ||
1120 | break; | ||
1121 | } | ||
1122 | |||
1123 | /** Output **/ | 1131 | /** Output **/ |
1124 | 1132 | ||
1125 | /* TODO: Output through core dsp. We'll still use our own PCM buffer | 1133 | /* TODO: Output through core dsp. We'll still use our own PCM buffer |
@@ -1257,6 +1265,7 @@ static void video_thread(void) | |||
1257 | char str[80]; | 1265 | char str[80]; |
1258 | int dither_index = 0; | 1266 | int dither_index = 0; |
1259 | uint32_t curr_time = 0; | 1267 | uint32_t curr_time = 0; |
1268 | uint32_t period = 0; /* Frame period in clock ticks */ | ||
1260 | uint32_t eta_audio = UINT_MAX, eta_video = 0; | 1269 | uint32_t eta_audio = UINT_MAX, eta_video = 0; |
1261 | int32_t eta_early = 0, eta_late = 0; | 1270 | int32_t eta_early = 0, eta_late = 0; |
1262 | int frame_drop_level = 0; | 1271 | int frame_drop_level = 0; |
@@ -1307,6 +1316,8 @@ static void video_thread(void) | |||
1307 | 1316 | ||
1308 | while (videostatus == STREAM_PAUSING) | 1317 | while (videostatus == STREAM_PAUSING) |
1309 | rb->sleep(HZ/10); | 1318 | rb->sleep(HZ/10); |
1319 | |||
1320 | continue; | ||
1310 | } | 1321 | } |
1311 | 1322 | ||
1312 | state = mpeg2_parse (mpeg2dec); | 1323 | state = mpeg2_parse (mpeg2dec); |
@@ -1336,7 +1347,6 @@ static void video_thread(void) | |||
1336 | case STATE_PICTURE: | 1347 | case STATE_PICTURE: |
1337 | { | 1348 | { |
1338 | /* A new picture is available - see if we should draw it */ | 1349 | /* A new picture is available - see if we should draw it */ |
1339 | uint32_t period; /* Frame period in clock ticks */ | ||
1340 | int32_t offset; /* Tick adjustment to keep sync */ | 1350 | int32_t offset; /* Tick adjustment to keep sync */ |
1341 | 1351 | ||
1342 | /* No limiting => no dropping so simply make sure skipping is off | 1352 | /* No limiting => no dropping so simply make sure skipping is off |
@@ -1344,12 +1354,12 @@ static void video_thread(void) | |||
1344 | if (!settings.limitfps) | 1354 | if (!settings.limitfps) |
1345 | goto picture_done; | 1355 | goto picture_done; |
1346 | 1356 | ||
1347 | period = TIME_TO_TICKS(info->sequence->frame_period); | ||
1348 | |||
1349 | /* Get presentation times in audio samples - quite accurate | 1357 | /* Get presentation times in audio samples - quite accurate |
1350 | enough */ | 1358 | enough - add previous frame duration if not stamped */ |
1351 | curr_time = (info->current_picture->flags & PIC_FLAG_TAGS) ? | 1359 | curr_time = (info->display_picture->flags & PIC_FLAG_TAGS) ? |
1352 | TS_TO_TICKS(info->current_picture->tag) : (curr_time + period); | 1360 | TS_TO_TICKS(info->display_picture->tag) : (curr_time + period); |
1361 | |||
1362 | period = TIME_TO_TICKS(info->sequence->frame_period); | ||
1353 | 1363 | ||
1354 | eta_video = curr_time; | 1364 | eta_video = curr_time; |
1355 | eta_audio = get_stream_time(); | 1365 | eta_audio = get_stream_time(); |
@@ -1442,21 +1452,32 @@ static void video_thread(void) | |||
1442 | if (frame_drop_level > 1 || offset > CLOCK_RATE*167/1000) | 1452 | if (frame_drop_level > 1 || offset > CLOCK_RATE*167/1000) |
1443 | { | 1453 | { |
1444 | /* Frame type: I/P/B/D */ | 1454 | /* Frame type: I/P/B/D */ |
1445 | int type = info->current_picture->flags & PIC_MASK_CODING_TYPE; | 1455 | int type = info->display_picture->flags & PIC_MASK_CODING_TYPE; |
1446 | 1456 | ||
1447 | /* Things are running a bit late or all frames are being | 1457 | /* Things are running a bit late or all frames are being |
1448 | dropped until a key frame */ | 1458 | dropped until a key frame */ |
1449 | 1459 | if (frame_drop_level > 1) | |
1450 | if (frame_drop_level > 1 && (type == I_TYPE || type == D_TYPE)) | 1460 | { |
1451 | frame_drop_level = 0; /* This frame can be drawn */ | 1461 | switch (type) |
1462 | { | ||
1463 | case PIC_FLAG_CODING_TYPE_I: | ||
1464 | case PIC_FLAG_CODING_TYPE_D: | ||
1465 | frame_drop_level = 0; /* This frame can be drawn */ | ||
1466 | } | ||
1467 | } | ||
1452 | 1468 | ||
1453 | if (frame_drop_level <= 1 && offset > CLOCK_RATE*250/1000) | 1469 | if (frame_drop_level <= 1 && offset > CLOCK_RATE*250/1000) |
1454 | { | 1470 | { |
1455 | /* Things are very, very late. Resort to stronger measures | 1471 | /* Things are very, very late. Resort to stronger measures |
1456 | to keep sync by dropping a I/D/P frame. Drawing cannot | 1472 | to keep sync by dropping a I/D/P frame. Drawing cannot |
1457 | take place again until the next key frame. */ | 1473 | take place again until the next key frame. */ |
1458 | if (type == I_TYPE || type == D_TYPE || type == P_TYPE) | 1474 | switch (type) |
1475 | { | ||
1476 | case PIC_FLAG_CODING_TYPE_I: | ||
1477 | case PIC_FLAG_CODING_TYPE_P: | ||
1478 | case PIC_FLAG_CODING_TYPE_D: | ||
1459 | frame_drop_level = 2; | 1479 | frame_drop_level = 2; |
1480 | } | ||
1460 | } | 1481 | } |
1461 | 1482 | ||
1462 | drop_frame = 1 << frame_drop_level; | 1483 | drop_frame = 1 << frame_drop_level; |
@@ -1466,12 +1487,18 @@ static void video_thread(void) | |||
1466 | /* Timeout has expired and this frame will be drawn if it | 1487 | /* Timeout has expired and this frame will be drawn if it |
1467 | is available. This may reverse the decision to drop a | 1488 | is available. This may reverse the decision to drop a |
1468 | key frame above. */ | 1489 | key frame above. */ |
1469 | if (frame_drop_level <= 1 || type == I_TYPE || type == D_TYPE) | 1490 | switch (type) |
1470 | { | 1491 | { |
1471 | drop_frame = 0; | 1492 | default: |
1493 | if (frame_drop_level <= 1) | ||
1494 | { | ||
1495 | case PIC_FLAG_CODING_TYPE_I: | ||
1496 | case PIC_FLAG_CODING_TYPE_D: | ||
1497 | drop_frame = 0; | ||
1498 | } | ||
1472 | } | 1499 | } |
1473 | } | 1500 | } |
1474 | else if (type == B_TYPE) | 1501 | else if (type == PIC_FLAG_CODING_TYPE_B) |
1475 | { | 1502 | { |
1476 | /* We want to drop something, so this B frame won't even be | 1503 | /* We want to drop something, so this B frame won't even be |
1477 | decoded. Drawing can happen on the next frame if so | 1504 | decoded. Drawing can happen on the next frame if so |
@@ -1538,7 +1565,7 @@ static void video_thread(void) | |||
1538 | if (clock_ticks != 0) | 1565 | if (clock_ticks != 0) |
1539 | fps = num_drawn*CLOCK_RATE*10ll / clock_ticks; | 1566 | fps = num_drawn*CLOCK_RATE*10ll / clock_ticks; |
1540 | 1567 | ||
1541 | rb->snprintf(str, sizeof(str), "%d.%d %d %d", | 1568 | rb->snprintf(str, sizeof(str), "%d.%d %d %d ", |
1542 | fps / 10, fps % 10, num_skipped, | 1569 | fps / 10, fps % 10, num_skipped, |
1543 | info->display_picture->temporal_reference); | 1570 | info->display_picture->temporal_reference); |
1544 | rb->lcd_putsxy(0, 0, str); | 1571 | rb->lcd_putsxy(0, 0, str); |