diff options
| author | Michael Sevakis <jethead71@rockbox.org> | 2011-01-03 16:41:19 +0000 |
|---|---|---|
| committer | Michael Sevakis <jethead71@rockbox.org> | 2011-01-03 16:41:19 +0000 |
| commit | b664f62e36b5f0ac296567e423816dab3811075d (patch) | |
| tree | 7ca49c59d7332d7c1e51139efa12466b6730e511 /apps/plugins/mpegplayer/video_thread.c | |
| parent | f8fde296a63dd06efef5cf71c9fdb2c26c5a3fd6 (diff) | |
| download | rockbox-b664f62e36b5f0ac296567e423816dab3811075d.zip rockbox-b664f62e36b5f0ac296567e423816dab3811075d.tar.gz rockbox-b664f62e36b5f0ac296567e423816dab3811075d.tar.bz2 rockbox-b664f62e36b5f0ac296567e423816dab3811075d.tar.xz | |
MPEGPlayer graphics mutation: Implement a more visible FPS display and remove the debugging info from it. Tweak thumbnailing and printing of unavailable frames.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@28960 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/mpegplayer/video_thread.c')
| -rw-r--r-- | apps/plugins/mpegplayer/video_thread.c | 129 |
1 files changed, 65 insertions, 64 deletions
diff --git a/apps/plugins/mpegplayer/video_thread.c b/apps/plugins/mpegplayer/video_thread.c index 69d94f8..aa88590 100644 --- a/apps/plugins/mpegplayer/video_thread.c +++ b/apps/plugins/mpegplayer/video_thread.c @@ -37,21 +37,23 @@ struct video_thread_data int state; /* Thread state */ int status; /* Media status */ struct queue_event ev; /* Our event queue to receive commands */ - int num_drawn; /* Number of frames drawn since reset */ - int num_skipped; /* Number of frames skipped since reset */ uint32_t eta_stream; /* Current time of stream */ uint32_t eta_video; /* Time that frame has been scheduled for */ int32_t eta_early; /* How early has the frame been decoded? */ int32_t eta_late; /* How late has the frame been decoded? */ int frame_drop_level; /* Drop severity */ int skip_level; /* Skip severity */ - long last_showfps; /* Last time the FPS display was updated */ long last_render; /* Last time a frame was drawn */ uint32_t curr_time; /* Current due time of frame */ uint32_t period; /* Frame period in clock ticks */ int syncf_perfect; /* Last sync fit result */ }; +/* Number drawn since reset */ +static int video_num_drawn SHAREDBSS_ATTR; +/* Number skipped since reset */ +static int video_num_skipped SHAREDBSS_ATTR; + /* TODO: Check if 4KB is appropriate - it works for my test streams, so maybe we can reduce it. */ #define VIDEO_STACKSIZE (4*1024) @@ -60,35 +62,6 @@ static struct event_queue video_str_queue SHAREDBSS_ATTR; static struct queue_sender_list video_str_queue_send SHAREDBSS_ATTR; struct stream video_str IBSS_ATTR; -static void draw_fps(struct video_thread_data *td) -{ - uint32_t start; - uint32_t clock_ticks = stream_get_ticks(&start); - int fps = 0; - int buf_pct; - char str[80]; - - clock_ticks -= start; - if (clock_ticks != 0) - fps = muldiv_uint32(CLOCK_RATE*100, td->num_drawn, clock_ticks); - - buf_pct = muldiv_uint32(100, pcm_output_used(), PCMOUT_BUFSIZE); - - rb->snprintf(str, sizeof(str), "v:%d.%02d %d %d a:%02d%% %d %d ", - /* Video information */ - fps / 100, fps % 100, td->num_skipped, - td->info->display_picture->temporal_reference, - /* Audio information */ - buf_pct, pcm_underruns, pcm_skipped); - mylcd_putsxy(0, 0, str); - - vo_lock(); - mylcd_update_rect(0, 0, LCD_WIDTH, 8); - vo_unlock(); - - td->last_showfps = *rb->current_tick; -} - #if defined(DEBUG) || defined(SIMULATOR) static unsigned char pic_coding_type_char(unsigned type) { @@ -452,6 +425,31 @@ sync_finished: return retval; } +static bool frame_print_handler(struct video_thread_data *td) +{ + bool retval; + uint8_t * const * buf = NULL; + + if (td->info != NULL && td->info->display_fbuf != NULL && + td->syncf_perfect > 0) + buf = td->info->display_fbuf->buf; + + if (td->ev.id == VIDEO_PRINT_THUMBNAIL) + { + /* Print a thumbnail of whatever was last decoded - scale and + * position to fill the specified rectangle */ + retval = vo_draw_frame_thumb(buf, (struct vo_rect *)td->ev.data); + } + else + { + /* Print the last frame decoded */ + vo_draw_frame(buf); + retval = buf != NULL; + } + + return retval; +} + /* This only returns to play or quit */ static void video_thread_msg(struct video_thread_data *td) { @@ -520,8 +518,7 @@ static void video_thread_msg(struct video_thread_data *td) if (td->ev.data) { - if (td->info != NULL && td->info->display_fbuf != NULL) - vo_draw_frame(td->info->display_fbuf->buf); + frame_print_handler(td); } else { @@ -547,10 +544,9 @@ static void video_thread_msg(struct video_thread_data *td) td->eta_late = 0; td->frame_drop_level = 0; td->skip_level = 0; - td->num_drawn = 0; - td->num_skipped = 0; - td->last_showfps = *rb->current_tick - HZ; - td->last_render = td->last_showfps; + td->last_render = *rb->current_tick - HZ; + video_num_drawn = 0; + video_num_skipped = 0; reply = true; break; @@ -573,28 +569,17 @@ static void video_thread_msg(struct video_thread_data *td) str_data_notify_received(&video_str); break; + case VIDEO_PRINT_FRAME: case VIDEO_PRINT_THUMBNAIL: - /* Print a thumbnail of whatever was last decoded - scale and - * position to fill the specified rectangle */ - if (td->info != NULL && td->info->display_fbuf != NULL) - { - vo_draw_frame_thumb(td->info->display_fbuf->buf, - (struct vo_rect *)td->ev.data); - reply = true; - } + reply = frame_print_handler(td); break; case VIDEO_SET_CLIP_RECT: vo_set_clip_rect((const struct vo_rect *)td->ev.data); break; - case VIDEO_PRINT_FRAME: - /* Print the last frame decoded */ - if (td->info != NULL && td->info->display_fbuf != NULL) - { - vo_draw_frame(td->info->display_fbuf->buf); - reply = true; - } + case VIDEO_GET_CLIP_RECT: + reply = vo_get_clip_rect((struct vo_rect *)td->ev.data); break; case VIDEO_GET_SIZE: @@ -621,6 +606,11 @@ static void video_thread_msg(struct video_thread_data *td) reply = video_str_scan(td, (struct str_sync_data *)td->ev.data); break; + case VIDEO_SET_POST_FRAME_CALLBACK: + vo_set_post_draw_callback((void (*)(void))td->ev.data); + reply = true; + break; + case STREAM_QUIT: /* Time to go - make thread exit */ td->state = TSTATE_EOS; @@ -802,6 +792,8 @@ static void video_thread(void) if (td.info->display_fbuf == NULL) break; /* No picture */ + td.syncf_perfect = 1; /* yes, a frame exists */ + /* Get presentation times in audio samples - quite accurate enough - add previous frame duration if not stamped */ td.curr_time = (td.info->display_picture->flags & PIC_FLAG_TAGS) ? @@ -902,8 +894,8 @@ static void video_thread(void) { /* This frame was set to skip so skip it after having updated timing information */ - td.num_skipped++; td.eta_early = INT32_MIN; + video_num_skipped++; goto picture_skip; } @@ -913,8 +905,8 @@ static void video_thread(void) /* Render drop was set previously but nothing was dropped in the decoder or it's been to long since drawing the last frame. */ td.skip_level = 0; - td.num_skipped++; td.eta_early = INT32_MIN; + video_num_skipped++; goto picture_skip; } @@ -970,18 +962,11 @@ static void video_thread(void) picture_draw: /* Record last frame time */ td.last_render = *rb->current_tick; + vo_draw_frame(td.info->display_fbuf->buf); - td.num_drawn++; + video_num_drawn++; picture_skip: - if (!settings.showfps) - break; - - if (TIME_BEFORE(*rb->current_tick, td.last_showfps + HZ)) - break; - - /* Calculate and display fps */ - draw_fps(&td); break; } @@ -1032,3 +1017,19 @@ void video_thread_exit(void) video_str.thread = 0; } } + + +/** Misc **/ +void video_thread_get_stats(struct video_output_stats *s) +{ + uint32_t start; + uint32_t now = stream_get_ticks(&start); + s->num_drawn = video_num_drawn; + s->num_skipped = video_num_skipped; + + s->fps = 0; + + if (now > start) + s->fps = muldiv_uint32(CLOCK_RATE*100, s->num_drawn, now - start); +} + |