summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2010-12-19 08:28:03 +0000
committerMichael Sevakis <jethead71@rockbox.org>2010-12-19 08:28:03 +0000
commit31af1a3ac21646c8f07b1b93e497d45a060ee36d (patch)
tree30b7541bd15a3291311c8d1b48b1b6a95d7a1ba5
parentfd01bf3e4cfedf073824b1a98662932796b6cd32 (diff)
downloadrockbox-31af1a3ac21646c8f07b1b93e497d45a060ee36d.tar.gz
rockbox-31af1a3ac21646c8f07b1b93e497d45a060ee36d.zip
MPEGPlayer: Move some code that's probably better situated in the stream manager rather than the parser. Fix visibility checking in video out. Extra message sending for new stream isn't needed; just do full decoder sequence reset when requesting dimensions.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@28855 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/plugins/mpegplayer/mpeg_parser.c172
-rw-r--r--apps/plugins/mpegplayer/parser.h2
-rw-r--r--apps/plugins/mpegplayer/stream_mgr.c48
-rw-r--r--apps/plugins/mpegplayer/video_out_rockbox.c6
-rw-r--r--apps/plugins/mpegplayer/video_thread.c12
5 files changed, 119 insertions, 121 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)
return pos;
}
-static bool prepare_image(uint32_t time)
-{
- struct stream_scan sk;
- int tries;
- int result;
-
- stream_scan_init(&sk);
-
- if (!str_send_msg(&video_str, STREAM_NEEDS_SYNC, time))
- {
- DEBUGF("Image was ready\n");
- return true; /* Should already have the image */
- }
-
-#ifdef HAVE_ADJUSTABLE_CPU_FREQ
- rb->cpu_boost(true); /* No interference with trigger_cpu_boost */
-#endif
-
- str_send_msg(&video_str, STREAM_RESET, 0);
-
- sk.pos = parser_can_seek() ?
- mpeg_parser_seek_PTS(time, video_str.id) : 0;
- sk.len = sk.pos;
- sk.dir = SSCAN_REVERSE;
-
- tries = 1;
-try_again:
-
- if (mpeg_parser_scan_start_code(&sk, MPEG_START_GOP))
- {
- DEBUGF("GOP found at: %ld\n", sk.pos);
-
- unsigned id = mpeg_parser_scan_pes(&sk);
-
- if (id != video_str.id && sk.pos > 0)
- {
- /* Not part of our stream */
- DEBUGF(" wrong stream: 0x%02x\n", id);
- goto try_again;
- }
-
- /* This will hit the PES header since it's known to be there */
- uint32_t pts = mpeg_parser_scan_pts(&sk, id);
-
- if (pts == INVALID_TIMESTAMP || pts > time)
- {
- DEBUGF(" wrong timestamp: %u\n", (unsigned)pts);
- goto try_again;
- }
- }
-
- str_parser.parms.sd.time = time;
- str_parser.parms.sd.sk.pos = MAX(sk.pos, 0);
- str_parser.parms.sd.sk.len = 1024*1024;
- str_parser.parms.sd.sk.dir = SSCAN_FORWARD;
-
- DEBUGF("thumb pos:%ld len:%ld\n", str_parser.parms.sd.sk.pos,
- (long)str_parser.parms.sd.sk.len);
-
- result = str_send_msg(&video_str, STREAM_SYNC,
- (intptr_t)&str_parser.parms.sd);
-
- if (result != STREAM_PERFECT_MATCH)
- {
- /* Two tries should be all that is nescessary to find the exact frame
- * if the first GOP actually started later than the timestamp - the
- * GOP just prior must then start on or earlier. */
- if (++tries <= 2)
- goto try_again;
- }
-
-#ifdef HAVE_ADJUSTABLE_CPU_FREQ
- rb->cpu_boost(false);
-#endif
-
- return result > STREAM_OK;
-}
-
static void prepare_audio(uint32_t time)
{
off_t pos;
@@ -1037,41 +959,82 @@ static int parse_elementary(struct stream *str, enum stream_parse_mode type)
return STREAM_OK;
}
-intptr_t parser_send_video_msg(long id, intptr_t data)
+bool parser_prepare_image(uint32_t time)
{
- intptr_t retval = 0;
+ struct stream_scan sk;
+ int tries;
+ int result;
+
+ stream_scan_init(&sk);
- if (video_str.thread != 0 && disk_buf.in_file >= 0)
+ if (!str_send_msg(&video_str, STREAM_NEEDS_SYNC, time))
{
- /* Hook certain messages since they involve multiple operations
- * behind the scenes */
- switch (id)
- {
- case VIDEO_DISPLAY_SHOW:
- if (data != 0 && disk_buf_status() == STREAM_STOPPED)
- { /* Only prepare image if showing and not playing */
- prepare_image(str_parser.last_seek_time);
- }
- break;
+ DEBUGF("Image was ready\n");
+ return true; /* Should already have the image */
+ }
- case VIDEO_PRINT_FRAME:
- if (data)
- break;
- case VIDEO_PRINT_THUMBNAIL:
- if (disk_buf_status() != STREAM_STOPPED)
- break; /* Prepare image if not playing */
+#ifdef HAVE_ADJUSTABLE_CPU_FREQ
+ rb->cpu_boost(true); /* No interference with trigger_cpu_boost */
+#endif
- if (!prepare_image(str_parser.last_seek_time))
- return false; /* Preparation failed */
+ str_send_msg(&video_str, STREAM_RESET, 0);
- /* Image ready - pass message to video thread */
- break;
+ sk.pos = parser_can_seek() ?
+ mpeg_parser_seek_PTS(time, video_str.id) : 0;
+ sk.len = sk.pos;
+ sk.dir = SSCAN_REVERSE;
+
+ tries = 1;
+try_again:
+
+ if (mpeg_parser_scan_start_code(&sk, MPEG_START_GOP))
+ {
+ DEBUGF("GOP found at: %ld\n", sk.pos);
+
+ unsigned id = mpeg_parser_scan_pes(&sk);
+
+ if (id != video_str.id && sk.pos > 0)
+ {
+ /* Not part of our stream */
+ DEBUGF(" wrong stream: 0x%02x\n", id);
+ goto try_again;
+ }
+
+ /* This will hit the PES header since it's known to be there */
+ uint32_t pts = mpeg_parser_scan_pts(&sk, id);
+
+ if (pts == INVALID_TIMESTAMP || pts > time)
+ {
+ DEBUGF(" wrong timestamp: %u\n", (unsigned)pts);
+ goto try_again;
}
+ }
+
+ str_parser.parms.sd.time = time;
+ str_parser.parms.sd.sk.pos = MAX(sk.pos, 0);
+ str_parser.parms.sd.sk.len = 1024*1024;
+ str_parser.parms.sd.sk.dir = SSCAN_FORWARD;
- retval = str_send_msg(&video_str, id, data);
+ DEBUGF("thumb pos:%ld len:%ld\n", str_parser.parms.sd.sk.pos,
+ (long)str_parser.parms.sd.sk.len);
+
+ result = str_send_msg(&video_str, STREAM_SYNC,
+ (intptr_t)&str_parser.parms.sd);
+
+ if (result != STREAM_PERFECT_MATCH)
+ {
+ /* Two tries should be all that is nescessary to find the exact frame
+ * if the first GOP actually started later than the timestamp - the
+ * GOP just prior must then start on or earlier. */
+ if (++tries <= 2)
+ goto try_again;
}
- return retval;
+#ifdef HAVE_ADJUSTABLE_CPU_FREQ
+ rb->cpu_boost(false);
+#endif
+
+ return result > STREAM_OK;
}
/* Seek parser to the specified time and return absolute time.
@@ -1095,7 +1058,7 @@ void parser_prepare_streaming(void)
DEBUGF("parser_prepare_streaming\n");
/* Prepare initial video frame */
- prepare_image(str_parser.last_seek_time);
+ parser_prepare_image(str_parser.last_seek_time);
/* Sync audio stream */
if (audio_str.start_pts != INVALID_TIMESTAMP)
@@ -1215,7 +1178,6 @@ int parser_init_stream(void)
void parser_close_stream(void)
{
- str_send_msg(&video_str, STREAM_CLOSE, 0);
stream_remove_streams();
parser_init_state();
}
diff --git a/apps/plugins/mpegplayer/parser.h b/apps/plugins/mpegplayer/parser.h
index 4c58d2b6ec..ba2181e98b 100644
--- a/apps/plugins/mpegplayer/parser.h
+++ b/apps/plugins/mpegplayer/parser.h
@@ -86,7 +86,7 @@ off_t mpeg_stream_stream_seek_PTS(uint32_t time, int id);
/* General parsing */
bool parser_init(void);
void str_initialize(struct stream *str, off_t pos);
-intptr_t parser_send_video_msg(long id, intptr_t data);
+bool parser_prepare_image(uint32_t time);
bool parser_get_video_size(struct vo_ext *sz);
int parser_init_stream(void);
void parser_close_stream(void);
diff --git a/apps/plugins/mpegplayer/stream_mgr.c b/apps/plugins/mpegplayer/stream_mgr.c
index b88c6d70c7..67ec16cbb6 100644
--- a/apps/plugins/mpegplayer/stream_mgr.c
+++ b/apps/plugins/mpegplayer/stream_mgr.c
@@ -668,13 +668,51 @@ void stream_clear_notify(struct stream *str, int for_msg)
}
}
+/* Special handling for certain messages since they involve multiple
+ * operations behind the scenes */
+static intptr_t send_video_msg(long id, intptr_t data)
+{
+ intptr_t retval = 0;
+
+ if (video_str.thread != 0 && disk_buf.in_file >= 0)
+ {
+
+ switch (id)
+ {
+ case VIDEO_DISPLAY_SHOW:
+ if (data != 0 && disk_buf_status() == STREAM_STOPPED)
+ { /* Only prepare image if showing and not playing */
+ parser_prepare_image(str_parser.last_seek_time);
+ }
+ break;
+
+ case VIDEO_PRINT_FRAME:
+ if (data)
+ break;
+ case VIDEO_PRINT_THUMBNAIL:
+ if (disk_buf_status() != STREAM_STOPPED)
+ break; /* Prepare image if not playing */
+
+ if (!parser_prepare_image(str_parser.last_seek_time))
+ return false; /* Preparation failed */
+
+ /* Image ready - pass message to video thread */
+ break;
+ }
+
+ retval = str_send_msg(&video_str, id, data);
+ }
+
+ return retval;
+}
+
/* Show/hide the video output */
bool stream_show_vo(bool show)
{
bool vis;
stream_mgr_lock();
- vis = parser_send_video_msg(VIDEO_DISPLAY_SHOW, show);
+ vis = send_video_msg(VIDEO_DISPLAY_SHOW, show);
#ifndef HAVE_LCD_COLOR
grey_show(show);
#endif
@@ -688,7 +726,7 @@ bool stream_vo_is_visible(void)
{
bool vis;
stream_mgr_lock();
- vis = parser_send_video_msg(VIDEO_DISPLAY_IS_VISIBLE, 0);
+ vis = send_video_msg(VIDEO_DISPLAY_IS_VISIBLE, 0);
stream_mgr_unlock();
return vis;
}
@@ -721,7 +759,7 @@ void stream_vo_set_clip(const struct vo_rect *rc)
rc = &stream_mgr.parms.rc;
}
- parser_send_video_msg(VIDEO_SET_CLIP_RECT, (intptr_t)rc);
+ send_video_msg(VIDEO_SET_CLIP_RECT, (intptr_t)rc);
stream_mgr_unlock();
}
@@ -750,7 +788,7 @@ bool stream_display_thumb(const struct vo_rect *rc)
stream_mgr_lock();
stream_mgr.parms.rc = *rc;
- retval = parser_send_video_msg(VIDEO_PRINT_THUMBNAIL,
+ retval = send_video_msg(VIDEO_PRINT_THUMBNAIL,
(intptr_t)&stream_mgr.parms.rc);
stream_mgr_unlock();
@@ -763,7 +801,7 @@ bool stream_draw_frame(bool no_prepare)
bool retval;
stream_mgr_lock();
- retval = parser_send_video_msg(VIDEO_PRINT_FRAME, no_prepare);
+ retval = send_video_msg(VIDEO_PRINT_FRAME, no_prepare);
stream_mgr_unlock();
diff --git a/apps/plugins/mpegplayer/video_out_rockbox.c b/apps/plugins/mpegplayer/video_out_rockbox.c
index cf47982ab7..fe3deafd01 100644
--- a/apps/plugins/mpegplayer/video_out_rockbox.c
+++ b/apps/plugins/mpegplayer/video_out_rockbox.c
@@ -116,9 +116,11 @@ static inline void yuv_blit(uint8_t * const * buf, int src_x, int src_y,
void vo_draw_frame(uint8_t * const * buf)
{
- if (vo.flags == 0)
+ if ((vo.flags & (VO_NON_NULL_RECT | VO_VISIBLE)) !=
+ (VO_NON_NULL_RECT | VO_VISIBLE))
{
- /* Frame is hidden - copout */
+ /* Frame is hidden - either by being set invisible or is clipped
+ * away - copout */
DEBUGF("vo hidden\n");
return;
}
diff --git a/apps/plugins/mpegplayer/video_thread.c b/apps/plugins/mpegplayer/video_thread.c
index 4ccdc8b844..69d94f8ba0 100644
--- a/apps/plugins/mpegplayer/video_thread.c
+++ b/apps/plugins/mpegplayer/video_thread.c
@@ -124,7 +124,8 @@ static int video_str_scan(struct video_thread_data *td,
tmp_str.hdr.pos = sd->sk.pos;
tmp_str.hdr.limit = sd->sk.pos + sd->sk.len;
- mpeg2_reset(td->mpeg2dec, false);
+ /* Fully reset if obtaining size for a new stream */
+ mpeg2_reset(td->mpeg2dec, td->ev.id == VIDEO_GET_SIZE);
mpeg2_skip(td->mpeg2dec, 1);
while (1)
@@ -503,12 +504,6 @@ static void video_thread_msg(struct video_thread_data *td)
reply = true;
break;
- case STREAM_CLOSE:
- vo_cleanup();
- mpeg2_close(td->mpeg2dec);
- reply = true;
- break;
-
case VIDEO_DISPLAY_IS_VISIBLE:
reply = vo_is_visible();
break;
@@ -605,8 +600,9 @@ static void video_thread_msg(struct video_thread_data *td)
case VIDEO_GET_SIZE:
{
if (td->state != TSTATE_INIT)
- break;
+ break; /* Can only use after a reset was issued */
+ /* This will reset the decoder in full for this particular event */
if (init_sequence(td))
{
reply = true;