summaryrefslogtreecommitdiff
path: root/apps/plugins/mpegplayer/mpeg_parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/mpegplayer/mpeg_parser.c')
-rw-r--r--apps/plugins/mpegplayer/mpeg_parser.c172
1 files changed, 67 insertions, 105 deletions
diff --git a/apps/plugins/mpegplayer/mpeg_parser.c b/apps/plugins/mpegplayer/mpeg_parser.c
index 1be11a467b..b683efe1c9 100644
--- a/apps/plugins/mpegplayer/mpeg_parser.c
+++ b/apps/plugins/mpegplayer/mpeg_parser.c
@@ -564,84 +564,6 @@ static off_t mpeg_parser_seek_PTS(uint32_t time, unsigned id)
564 return pos; 564 return pos;
565} 565}
566 566
567static bool prepare_image(uint32_t time)
568{
569 struct stream_scan sk;
570 int tries;
571 int result;
572
573 stream_scan_init(&sk);
574
575 if (!str_send_msg(&video_str, STREAM_NEEDS_SYNC, time))
576 {
577 DEBUGF("Image was ready\n");
578 return true; /* Should already have the image */
579 }
580
581#ifdef HAVE_ADJUSTABLE_CPU_FREQ
582 rb->cpu_boost(true); /* No interference with trigger_cpu_boost */
583#endif
584
585 str_send_msg(&video_str, STREAM_RESET, 0);
586
587 sk.pos = parser_can_seek() ?
588 mpeg_parser_seek_PTS(time, video_str.id) : 0;
589 sk.len = sk.pos;
590 sk.dir = SSCAN_REVERSE;
591
592 tries = 1;
593try_again:
594
595 if (mpeg_parser_scan_start_code(&sk, MPEG_START_GOP))
596 {
597 DEBUGF("GOP found at: %ld\n", sk.pos);
598
599 unsigned id = mpeg_parser_scan_pes(&sk);
600
601 if (id != video_str.id && sk.pos > 0)
602 {
603 /* Not part of our stream */
604 DEBUGF(" wrong stream: 0x%02x\n", id);
605 goto try_again;
606 }
607
608 /* This will hit the PES header since it's known to be there */
609 uint32_t pts = mpeg_parser_scan_pts(&sk, id);
610
611 if (pts == INVALID_TIMESTAMP || pts > time)
612 {
613 DEBUGF(" wrong timestamp: %u\n", (unsigned)pts);
614 goto try_again;
615 }
616 }
617
618 str_parser.parms.sd.time = time;
619 str_parser.parms.sd.sk.pos = MAX(sk.pos, 0);
620 str_parser.parms.sd.sk.len = 1024*1024;
621 str_parser.parms.sd.sk.dir = SSCAN_FORWARD;
622
623 DEBUGF("thumb pos:%ld len:%ld\n", str_parser.parms.sd.sk.pos,
624 (long)str_parser.parms.sd.sk.len);
625
626 result = str_send_msg(&video_str, STREAM_SYNC,
627 (intptr_t)&str_parser.parms.sd);
628
629 if (result != STREAM_PERFECT_MATCH)
630 {
631 /* Two tries should be all that is nescessary to find the exact frame
632 * if the first GOP actually started later than the timestamp - the
633 * GOP just prior must then start on or earlier. */
634 if (++tries <= 2)
635 goto try_again;
636 }
637
638#ifdef HAVE_ADJUSTABLE_CPU_FREQ
639 rb->cpu_boost(false);
640#endif
641
642 return result > STREAM_OK;
643}
644
645static void prepare_audio(uint32_t time) 567static void prepare_audio(uint32_t time)
646{ 568{
647 off_t pos; 569 off_t pos;
@@ -1037,41 +959,82 @@ static int parse_elementary(struct stream *str, enum stream_parse_mode type)
1037 return STREAM_OK; 959 return STREAM_OK;
1038} 960}
1039 961
1040intptr_t parser_send_video_msg(long id, intptr_t data) 962bool parser_prepare_image(uint32_t time)
1041{ 963{
1042 intptr_t retval = 0; 964 struct stream_scan sk;
965 int tries;
966 int result;
967
968 stream_scan_init(&sk);
1043 969
1044 if (video_str.thread != 0 && disk_buf.in_file >= 0) 970 if (!str_send_msg(&video_str, STREAM_NEEDS_SYNC, time))
1045 { 971 {
1046 /* Hook certain messages since they involve multiple operations 972 DEBUGF("Image was ready\n");
1047 * behind the scenes */ 973 return true; /* Should already have the image */
1048 switch (id) 974 }
1049 {
1050 case VIDEO_DISPLAY_SHOW:
1051 if (data != 0 && disk_buf_status() == STREAM_STOPPED)
1052 { /* Only prepare image if showing and not playing */
1053 prepare_image(str_parser.last_seek_time);
1054 }
1055 break;
1056 975
1057 case VIDEO_PRINT_FRAME: 976#ifdef HAVE_ADJUSTABLE_CPU_FREQ
1058 if (data) 977 rb->cpu_boost(true); /* No interference with trigger_cpu_boost */
1059 break; 978#endif
1060 case VIDEO_PRINT_THUMBNAIL:
1061 if (disk_buf_status() != STREAM_STOPPED)
1062 break; /* Prepare image if not playing */
1063 979
1064 if (!prepare_image(str_parser.last_seek_time)) 980 str_send_msg(&video_str, STREAM_RESET, 0);
1065 return false; /* Preparation failed */
1066 981
1067 /* Image ready - pass message to video thread */ 982 sk.pos = parser_can_seek() ?
1068 break; 983 mpeg_parser_seek_PTS(time, video_str.id) : 0;
984 sk.len = sk.pos;
985 sk.dir = SSCAN_REVERSE;
986
987 tries = 1;
988try_again:
989
990 if (mpeg_parser_scan_start_code(&sk, MPEG_START_GOP))
991 {
992 DEBUGF("GOP found at: %ld\n", sk.pos);
993
994 unsigned id = mpeg_parser_scan_pes(&sk);
995
996 if (id != video_str.id && sk.pos > 0)
997 {
998 /* Not part of our stream */
999 DEBUGF(" wrong stream: 0x%02x\n", id);
1000 goto try_again;
1001 }
1002
1003 /* This will hit the PES header since it's known to be there */
1004 uint32_t pts = mpeg_parser_scan_pts(&sk, id);
1005
1006 if (pts == INVALID_TIMESTAMP || pts > time)
1007 {
1008 DEBUGF(" wrong timestamp: %u\n", (unsigned)pts);
1009 goto try_again;
1069 } 1010 }
1011 }
1012
1013 str_parser.parms.sd.time = time;
1014 str_parser.parms.sd.sk.pos = MAX(sk.pos, 0);
1015 str_parser.parms.sd.sk.len = 1024*1024;
1016 str_parser.parms.sd.sk.dir = SSCAN_FORWARD;
1070 1017
1071 retval = str_send_msg(&video_str, id, data); 1018 DEBUGF("thumb pos:%ld len:%ld\n", str_parser.parms.sd.sk.pos,
1019 (long)str_parser.parms.sd.sk.len);
1020
1021 result = str_send_msg(&video_str, STREAM_SYNC,
1022 (intptr_t)&str_parser.parms.sd);
1023
1024 if (result != STREAM_PERFECT_MATCH)
1025 {
1026 /* Two tries should be all that is nescessary to find the exact frame
1027 * if the first GOP actually started later than the timestamp - the
1028 * GOP just prior must then start on or earlier. */
1029 if (++tries <= 2)
1030 goto try_again;
1072 } 1031 }
1073 1032
1074 return retval; 1033#ifdef HAVE_ADJUSTABLE_CPU_FREQ
1034 rb->cpu_boost(false);
1035#endif
1036
1037 return result > STREAM_OK;
1075} 1038}
1076 1039
1077/* Seek parser to the specified time and return absolute time. 1040/* Seek parser to the specified time and return absolute time.
@@ -1095,7 +1058,7 @@ void parser_prepare_streaming(void)
1095 DEBUGF("parser_prepare_streaming\n"); 1058 DEBUGF("parser_prepare_streaming\n");
1096 1059
1097 /* Prepare initial video frame */ 1060 /* Prepare initial video frame */
1098 prepare_image(str_parser.last_seek_time); 1061 parser_prepare_image(str_parser.last_seek_time);
1099 1062
1100 /* Sync audio stream */ 1063 /* Sync audio stream */
1101 if (audio_str.start_pts != INVALID_TIMESTAMP) 1064 if (audio_str.start_pts != INVALID_TIMESTAMP)
@@ -1215,7 +1178,6 @@ int parser_init_stream(void)
1215 1178
1216void parser_close_stream(void) 1179void parser_close_stream(void)
1217{ 1180{
1218 str_send_msg(&video_str, STREAM_CLOSE, 0);
1219 stream_remove_streams(); 1181 stream_remove_streams();
1220 parser_init_state(); 1182 parser_init_state();
1221} 1183}