forked from len0rd/rockbox
Initial WVS for mpegplayer. Adjusts to the user's preferred font and uses FF/RW preferences set for playback. Picked a random color for the base WVS color but it could be configured. Some engine tweaks to accomodate it since certain nescessities are clearer now. Fix a clipped YUV output bug in the SIM.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15991 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
d1cb32a93f
commit
a5fc3f4df4
18 changed files with 1341 additions and 105 deletions
|
@ -580,6 +580,8 @@ static const struct plugin_api rockbox_api = {
|
||||||
trigger_cpu_boost,
|
trigger_cpu_boost,
|
||||||
cancel_cpu_boost,
|
cancel_cpu_boost,
|
||||||
#endif
|
#endif
|
||||||
|
sound_unit,
|
||||||
|
sound_val2phys,
|
||||||
#endif /* CONFIG_CODEC == SWCODEC */
|
#endif /* CONFIG_CODEC == SWCODEC */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -119,7 +119,7 @@
|
||||||
#define PLUGIN_MAGIC 0x526F634B /* RocK */
|
#define PLUGIN_MAGIC 0x526F634B /* RocK */
|
||||||
|
|
||||||
/* increase this every time the api struct changes */
|
/* increase this every time the api struct changes */
|
||||||
#define PLUGIN_API_VERSION 92
|
#define PLUGIN_API_VERSION 93
|
||||||
|
|
||||||
/* update this to latest version if a change to the api struct breaks
|
/* update this to latest version if a change to the api struct breaks
|
||||||
backwards compatibility (and please take the opportunity to sort in any
|
backwards compatibility (and please take the opportunity to sort in any
|
||||||
|
@ -715,6 +715,8 @@ struct plugin_api {
|
||||||
void (*trigger_cpu_boost)(void);
|
void (*trigger_cpu_boost)(void);
|
||||||
void (*cancel_cpu_boost)(void);
|
void (*cancel_cpu_boost)(void);
|
||||||
#endif
|
#endif
|
||||||
|
const char * (*sound_unit)(int setting);
|
||||||
|
int (*sound_val2phys)(int setting, int value);
|
||||||
#endif /* CONFIG_CODEC == SWCODEC */
|
#endif /* CONFIG_CODEC == SWCODEC */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,11 @@ flipit_cursor.16x13x1.bmp
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* MPEGplayer */
|
||||||
|
mpegplayer_status_icons_8x8x1.bmp
|
||||||
|
mpegplayer_status_icons_12x12x1.bmp
|
||||||
|
mpegplayer_status_icons_16x16x1.bmp
|
||||||
|
|
||||||
#if LCD_WIDTH == 160 && LCD_HEIGHT == 128 && LCD_DEPTH < 16
|
#if LCD_WIDTH == 160 && LCD_HEIGHT == 128 && LCD_DEPTH < 16
|
||||||
superdom_boarditems.160x128x1.bmp
|
superdom_boarditems.160x128x1.bmp
|
||||||
#endif
|
#endif
|
||||||
|
|
BIN
apps/plugins/bitmaps/mono/mpegplayer_status_icons_12x12x1.bmp
Normal file
BIN
apps/plugins/bitmaps/mono/mpegplayer_status_icons_12x12x1.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 158 B |
BIN
apps/plugins/bitmaps/mono/mpegplayer_status_icons_16x16x1.bmp
Normal file
BIN
apps/plugins/bitmaps/mono/mpegplayer_status_icons_16x16x1.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 254 B |
BIN
apps/plugins/bitmaps/mono/mpegplayer_status_icons_8x8x1.bmp
Normal file
BIN
apps/plugins/bitmaps/mono/mpegplayer_status_icons_8x8x1.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 126 B |
|
@ -43,7 +43,7 @@ libmad-mpegplayer:
|
||||||
ifndef SIMVER
|
ifndef SIMVER
|
||||||
$(OBJDIR)/mpegplayer.elf: $(OBJS) $(LINKFILE) $(BUILDDIR)/libmad-mpegplayer.a
|
$(OBJDIR)/mpegplayer.elf: $(OBJS) $(LINKFILE) $(BUILDDIR)/libmad-mpegplayer.a
|
||||||
$(call PRINTS,LD $(@F))$(CC) $(CFLAGS) -o $@ $(OBJS) -L$(BUILDDIR) -lplugin -lmad-mpegplayer -lgcc\
|
$(call PRINTS,LD $(@F))$(CC) $(CFLAGS) -o $@ $(OBJS) -L$(BUILDDIR) -lplugin -lmad-mpegplayer -lgcc\
|
||||||
-T$(LINKFILE) -Wl,-Map,$(OBJDIR)/mpegplayer.map
|
$(LINKBITMAPS) -T$(LINKFILE) -Wl,-Map,$(OBJDIR)/mpegplayer.map
|
||||||
|
|
||||||
$(OUTPUT): $(OBJDIR)/mpegplayer.elf
|
$(OUTPUT): $(OBJDIR)/mpegplayer.elf
|
||||||
$(call PRINTS,OBJCOPY $(@F))$(OC) -O binary $< $@
|
$(call PRINTS,OBJCOPY $(@F))$(OC) -O binary $< $@
|
||||||
|
@ -51,7 +51,7 @@ else
|
||||||
# This is the SDL simulator version
|
# This is the SDL simulator version
|
||||||
|
|
||||||
$(OUTPUT): $(OBJS) $(BUILDDIR)/libmad-mpegplayer.a
|
$(OUTPUT): $(OBJS) $(BUILDDIR)/libmad-mpegplayer.a
|
||||||
$(call PRINTS,LD $(@F))$(CC) $(CFLAGS) $(SHARED_FLAG) $(OBJS) -L$(BUILDDIR) -lplugin -lmad-mpegplayer -o $@
|
$(call PRINTS,LD $(@F))$(CC) $(CFLAGS) $(SHARED_FLAG) $(OBJS) -L$(BUILDDIR) -lplugin $(LINKBITMAPS) -lmad-mpegplayer -o $@
|
||||||
ifeq ($(findstring CYGWIN,$(UNAME)),CYGWIN)
|
ifeq ($(findstring CYGWIN,$(UNAME)),CYGWIN)
|
||||||
# 'x' must be kept or you'll have "Win32 error 5"
|
# 'x' must be kept or you'll have "Win32 error 5"
|
||||||
# $ fgrep 5 /usr/include/w32api/winerror.h | head -1
|
# $ fgrep 5 /usr/include/w32api/winerror.h | head -1
|
||||||
|
|
|
@ -140,9 +140,8 @@ static void audio_queue_reset(void)
|
||||||
audio_queue.used = 0;
|
audio_queue.used = 0;
|
||||||
audio_queue.read = 0;
|
audio_queue.read = 0;
|
||||||
audio_queue.write = 0;
|
audio_queue.write = 0;
|
||||||
|
rb->memset(audio_queue.descs, 0, sizeof (audio_queue.descs));
|
||||||
audio_queue.curr = audiodesc_queue_head();
|
audio_queue.curr = audiodesc_queue_head();
|
||||||
audio_queue.curr->time = 0;
|
|
||||||
audio_queue.curr->size = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void audio_queue_advance_pos(ssize_t len)
|
static void audio_queue_advance_pos(ssize_t len)
|
||||||
|
|
|
@ -104,6 +104,9 @@ static inline bool disk_buf_is_data_ready(struct stream_hdr *sh,
|
||||||
bool disk_buf_init(void);
|
bool disk_buf_init(void);
|
||||||
void disk_buf_exit(void);
|
void disk_buf_exit(void);
|
||||||
|
|
||||||
|
static inline int disk_buf_status(void)
|
||||||
|
{ return disk_buf.status; }
|
||||||
|
|
||||||
int disk_buf_open(const char *filename);
|
int disk_buf_open(const char *filename);
|
||||||
void disk_buf_close(void);
|
void disk_buf_close(void);
|
||||||
ssize_t _disk_buf_getbuffer(size_t size, void **pp, void **pwrap,
|
ssize_t _disk_buf_getbuffer(size_t size, void **pp, void **pwrap,
|
||||||
|
|
|
@ -1012,15 +1012,17 @@ intptr_t parser_send_video_msg(long id, intptr_t data)
|
||||||
switch (id)
|
switch (id)
|
||||||
{
|
{
|
||||||
case VIDEO_DISPLAY_SHOW:
|
case VIDEO_DISPLAY_SHOW:
|
||||||
if (data != 0 && stream_status() != STREAM_PLAYING)
|
if (data != 0 && disk_buf_status() == STREAM_STOPPED)
|
||||||
{ /* Only prepare image if showing and not playing */
|
{ /* Only prepare image if showing and not playing */
|
||||||
prepare_image(str_parser.last_seek_time);
|
prepare_image(str_parser.last_seek_time);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIDEO_PRINT_FRAME:
|
case VIDEO_PRINT_FRAME:
|
||||||
|
if (data)
|
||||||
|
break;
|
||||||
case VIDEO_PRINT_THUMBNAIL:
|
case VIDEO_PRINT_THUMBNAIL:
|
||||||
if (stream_status() == STREAM_PLAYING)
|
if (disk_buf_status() != STREAM_STOPPED)
|
||||||
break; /* Prepare image if not playing */
|
break; /* Prepare image if not playing */
|
||||||
|
|
||||||
if (!prepare_image(str_parser.last_seek_time))
|
if (!prepare_image(str_parser.last_seek_time))
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -251,6 +251,7 @@ static void set_stream_clock(uint32_t time)
|
||||||
static uint32_t time_from_whence(uint32_t time, int whence)
|
static uint32_t time_from_whence(uint32_t time, int whence)
|
||||||
{
|
{
|
||||||
int64_t currtime;
|
int64_t currtime;
|
||||||
|
uint32_t start;
|
||||||
|
|
||||||
switch (whence)
|
switch (whence)
|
||||||
{
|
{
|
||||||
|
@ -262,12 +263,8 @@ static uint32_t time_from_whence(uint32_t time, int whence)
|
||||||
case SEEK_CUR:
|
case SEEK_CUR:
|
||||||
/* Seek forward or backward from the current time
|
/* Seek forward or backward from the current time
|
||||||
* (time = signed offset from current) */
|
* (time = signed offset from current) */
|
||||||
if (stream_mgr.seeked)
|
currtime = stream_get_seek_time(&start);
|
||||||
currtime = str_parser.last_seek_time;
|
currtime -= start;
|
||||||
else
|
|
||||||
currtime = TICKS_TO_TS(pcm_output_get_clock());
|
|
||||||
|
|
||||||
currtime -= str_parser.start_pts;
|
|
||||||
currtime += (int32_t)time;
|
currtime += (int32_t)time;
|
||||||
|
|
||||||
if (currtime < 0)
|
if (currtime < 0)
|
||||||
|
@ -525,27 +522,28 @@ static void stream_on_stop(bool reply)
|
||||||
|
|
||||||
if (status != STREAM_STOPPED)
|
if (status != STREAM_STOPPED)
|
||||||
{
|
{
|
||||||
/* Not stopped = paused or playing */
|
|
||||||
stream_mgr.seeked = false;
|
|
||||||
|
|
||||||
/* Pause the clock */
|
/* Pause the clock */
|
||||||
pcm_output_play_pause(false);
|
pcm_output_play_pause(false);
|
||||||
|
|
||||||
|
/* Assume invalidity */
|
||||||
|
stream_mgr.resume_time = 0;
|
||||||
|
|
||||||
if (stream_can_seek())
|
if (stream_can_seek())
|
||||||
{
|
{
|
||||||
/* Read the current stream time */
|
/* Read the current stream time or the last seeked position */
|
||||||
uint32_t time = TICKS_TO_TS(pcm_output_get_clock());
|
uint32_t start;
|
||||||
|
uint32_t time = stream_get_seek_time(&start);
|
||||||
/* Assume invalidity */
|
|
||||||
stream_mgr.resume_time = 0;
|
|
||||||
|
|
||||||
if (time >= str_parser.start_pts && time < str_parser.end_pts)
|
if (time >= str_parser.start_pts && time < str_parser.end_pts)
|
||||||
{
|
{
|
||||||
/* Save the current stream time */
|
/* Save the current stream time */
|
||||||
stream_mgr.resume_time = time - str_parser.start_pts;
|
stream_mgr.resume_time = time - start;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Not stopped = paused or playing */
|
||||||
|
stream_mgr.seeked = false;
|
||||||
|
|
||||||
/* Stop buffering */
|
/* Stop buffering */
|
||||||
disk_buf_send_msg(STREAM_STOP, 0);
|
disk_buf_send_msg(STREAM_STOP, 0);
|
||||||
|
|
||||||
|
@ -578,10 +576,10 @@ static void stream_on_seek(struct stream_seek_data *skd)
|
||||||
if (stream_mgr.filename == NULL)
|
if (stream_mgr.filename == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
stream_mgr_reply_msg(STREAM_OK);
|
|
||||||
|
|
||||||
stream_keep_disk_active();
|
stream_keep_disk_active();
|
||||||
|
|
||||||
|
stream_mgr_reply_msg(STREAM_OK);
|
||||||
|
|
||||||
stream_mgr_lock();
|
stream_mgr_lock();
|
||||||
|
|
||||||
if (!stream_can_seek())
|
if (!stream_can_seek())
|
||||||
|
@ -705,9 +703,11 @@ bool stream_show_vo(bool show)
|
||||||
|
|
||||||
vis = parser_send_video_msg(VIDEO_DISPLAY_SHOW, show);
|
vis = parser_send_video_msg(VIDEO_DISPLAY_SHOW, show);
|
||||||
#ifndef HAVE_LCD_COLOR
|
#ifndef HAVE_LCD_COLOR
|
||||||
GRAY_VIDEO_FLUSH_ICACHE();
|
GRAY_VIDEO_INVALIDATE_ICACHE();
|
||||||
GRAY_INVALIDATE_ICACHE();
|
GRAY_INVALIDATE_ICACHE();
|
||||||
|
|
||||||
gray_show(show);
|
gray_show(show);
|
||||||
|
|
||||||
GRAY_FLUSH_ICACHE();
|
GRAY_FLUSH_ICACHE();
|
||||||
#endif
|
#endif
|
||||||
stream_mgr_unlock();
|
stream_mgr_unlock();
|
||||||
|
@ -743,6 +743,32 @@ bool stream_vo_get_size(struct vo_ext *sz)
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void stream_vo_set_clip(const struct vo_rect *rc)
|
||||||
|
{
|
||||||
|
stream_mgr_lock();
|
||||||
|
|
||||||
|
if (rc)
|
||||||
|
{
|
||||||
|
stream_mgr.parms.rc = *rc;
|
||||||
|
rc = &stream_mgr.parms.rc;
|
||||||
|
}
|
||||||
|
#ifndef HAVE_LCD_COLOR
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vo_rect_set_ext(&stream_mgr.parms.rc, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
|
||||||
|
rc = &stream_mgr.parms.rc;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
parser_send_video_msg(VIDEO_SET_CLIP_RECT, (intptr_t)rc);
|
||||||
|
|
||||||
|
#ifndef HAVE_LCD_COLOR
|
||||||
|
stream_set_gray_rect(rc);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
stream_mgr_unlock();
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef HAVE_LCD_COLOR
|
#ifndef HAVE_LCD_COLOR
|
||||||
/* Set the rectangle for the gray video overlay - clipped to screen */
|
/* Set the rectangle for the gray video overlay - clipped to screen */
|
||||||
bool stream_set_gray_rect(const struct vo_rect *rc)
|
bool stream_set_gray_rect(const struct vo_rect *rc)
|
||||||
|
@ -756,21 +782,38 @@ bool stream_set_gray_rect(const struct vo_rect *rc)
|
||||||
|
|
||||||
if (vo_rect_intersect(&rc_gray, &rc_gray, rc))
|
if (vo_rect_intersect(&rc_gray, &rc_gray, rc))
|
||||||
{
|
{
|
||||||
bool vo_vis = stream_show_vo(false);
|
bool vis = parser_send_video_msg(VIDEO_DISPLAY_SHOW, false);
|
||||||
|
|
||||||
GRAY_VIDEO_FLUSH_ICACHE();
|
/* The impudence! Keeps the image from disappearing anyway. */
|
||||||
|
#ifdef SIMULATOR
|
||||||
|
rb->sim_lcd_ex_init(0, NULL);
|
||||||
|
#else
|
||||||
|
rb->timer_unregister();
|
||||||
|
#endif
|
||||||
|
GRAY_VIDEO_INVALIDATE_ICACHE();
|
||||||
GRAY_INVALIDATE_ICACHE();
|
GRAY_INVALIDATE_ICACHE();
|
||||||
|
|
||||||
|
vo_lock();
|
||||||
|
|
||||||
gray_init(rb, stream_mgr.graymem, stream_mgr.graysize,
|
gray_init(rb, stream_mgr.graymem, stream_mgr.graysize,
|
||||||
false, rc_gray.r - rc_gray.l, rc_gray.b - rc_gray.t,
|
false, rc_gray.r - rc_gray.l, rc_gray.b - rc_gray.t,
|
||||||
32, 2<<8, NULL);
|
32, 2<<8, NULL);
|
||||||
|
|
||||||
gray_set_position(rc_gray.l, rc_gray.t);
|
gray_set_position(rc_gray.l, rc_gray.t);
|
||||||
GRAY_FLUSH_ICACHE();
|
|
||||||
|
|
||||||
if (vo_vis)
|
vo_unlock();
|
||||||
|
|
||||||
|
GRAY_INVALIDATE_ICACHE();
|
||||||
|
|
||||||
|
if (stream_mgr.status != STREAM_PLAYING)
|
||||||
|
parser_send_video_msg(VIDEO_PRINT_FRAME, true);
|
||||||
|
|
||||||
|
GRAY_VIDEO_FLUSH_ICACHE();
|
||||||
|
|
||||||
|
if (vis)
|
||||||
{
|
{
|
||||||
stream_show_vo(true);
|
gray_show(true);
|
||||||
|
parser_send_video_msg(VIDEO_DISPLAY_SHOW, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -784,9 +827,11 @@ void stream_gray_show(bool show)
|
||||||
{
|
{
|
||||||
stream_mgr_lock();
|
stream_mgr_lock();
|
||||||
|
|
||||||
GRAY_VIDEO_FLUSH_ICACHE();
|
GRAY_VIDEO_INVALIDATE_ICACHE();
|
||||||
GRAY_INVALIDATE_ICACHE();
|
GRAY_INVALIDATE_ICACHE();
|
||||||
|
|
||||||
gray_show(show);
|
gray_show(show);
|
||||||
|
|
||||||
GRAY_FLUSH_ICACHE();
|
GRAY_FLUSH_ICACHE();
|
||||||
|
|
||||||
stream_mgr_unlock();
|
stream_mgr_unlock();
|
||||||
|
@ -803,11 +848,32 @@ bool stream_display_thumb(const struct vo_rect *rc)
|
||||||
|
|
||||||
stream_mgr_lock();
|
stream_mgr_lock();
|
||||||
|
|
||||||
|
GRAY_INVALIDATE_ICACHE();
|
||||||
|
|
||||||
stream_mgr.parms.rc = *rc;
|
stream_mgr.parms.rc = *rc;
|
||||||
retval = parser_send_video_msg(VIDEO_PRINT_THUMBNAIL,
|
retval = parser_send_video_msg(VIDEO_PRINT_THUMBNAIL,
|
||||||
(intptr_t)&stream_mgr.parms.rc);
|
(intptr_t)&stream_mgr.parms.rc);
|
||||||
|
|
||||||
|
GRAY_VIDEO_FLUSH_ICACHE();
|
||||||
|
|
||||||
stream_mgr_unlock();
|
stream_mgr_unlock();
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool stream_draw_frame(bool no_prepare)
|
||||||
|
{
|
||||||
|
bool retval;
|
||||||
|
stream_mgr_lock();
|
||||||
|
|
||||||
|
GRAY_INVALIDATE_ICACHE();
|
||||||
|
|
||||||
|
retval = parser_send_video_msg(VIDEO_PRINT_FRAME, no_prepare);
|
||||||
|
|
||||||
|
GRAY_VIDEO_FLUSH_ICACHE();
|
||||||
|
|
||||||
|
stream_mgr_unlock();
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -826,6 +892,25 @@ uint32_t stream_get_resume_time(void)
|
||||||
return resume_time;
|
return resume_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t stream_get_seek_time(uint32_t *start)
|
||||||
|
{
|
||||||
|
uint32_t time;
|
||||||
|
|
||||||
|
stream_mgr_lock();
|
||||||
|
|
||||||
|
if (stream_mgr.seeked)
|
||||||
|
time = str_parser.last_seek_time;
|
||||||
|
else
|
||||||
|
time = TICKS_TO_TS(pcm_output_get_clock());
|
||||||
|
|
||||||
|
if (start != NULL)
|
||||||
|
*start = str_parser.start_pts;
|
||||||
|
|
||||||
|
stream_mgr_unlock();
|
||||||
|
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
/* Returns the smallest file window that includes all active streams'
|
/* Returns the smallest file window that includes all active streams'
|
||||||
* windows */
|
* windows */
|
||||||
static bool stream_get_window_callback(struct list_item *item,
|
static bool stream_get_window_callback(struct list_item *item,
|
||||||
|
|
|
@ -105,6 +105,9 @@ int stream_seek(uint32_t time, int whence);
|
||||||
/* Show/Hide the video image at the current seekpoint */
|
/* Show/Hide the video image at the current seekpoint */
|
||||||
bool stream_show_vo(bool show);
|
bool stream_show_vo(bool show);
|
||||||
|
|
||||||
|
/* Set the visible section of video */
|
||||||
|
void stream_vo_set_clip(const struct vo_rect *rc);
|
||||||
|
|
||||||
#ifndef HAVE_LCD_COLOR
|
#ifndef HAVE_LCD_COLOR
|
||||||
/* Set the gray overlay rectangle */
|
/* Set the gray overlay rectangle */
|
||||||
bool stream_set_gray_rect(const struct vo_rect *rc);
|
bool stream_set_gray_rect(const struct vo_rect *rc);
|
||||||
|
@ -114,12 +117,19 @@ void stream_gray_show(bool show);
|
||||||
/* Display thumbnail of the current seekpoint */
|
/* Display thumbnail of the current seekpoint */
|
||||||
bool stream_display_thumb(const struct vo_rect *rc);
|
bool stream_display_thumb(const struct vo_rect *rc);
|
||||||
|
|
||||||
|
/* Draw the frame at the current position */
|
||||||
|
bool stream_draw_frame(bool no_prepare);
|
||||||
|
|
||||||
/* Return video dimensions */
|
/* Return video dimensions */
|
||||||
bool stream_vo_get_size(struct vo_ext *sz);
|
bool stream_vo_get_size(struct vo_ext *sz);
|
||||||
|
|
||||||
/* Returns the resume time in timestamp ticks */
|
/* Returns the resume time in timestamp ticks */
|
||||||
uint32_t stream_get_resume_time(void);
|
uint32_t stream_get_resume_time(void);
|
||||||
|
|
||||||
|
/* Returns stream_get_time if no seek is pending or else the
|
||||||
|
last time give to seek */
|
||||||
|
uint32_t stream_get_seek_time(uint32_t *start);
|
||||||
|
|
||||||
/* Return the absolute stream time in clock ticks - adjusted by
|
/* Return the absolute stream time in clock ticks - adjusted by
|
||||||
* master clock stream via audio timestamps */
|
* master clock stream via audio timestamps */
|
||||||
static inline uint32_t stream_get_time(void)
|
static inline uint32_t stream_get_time(void)
|
||||||
|
|
|
@ -106,6 +106,7 @@ enum stream_message
|
||||||
VIDEO_GET_SIZE, /* Get the video dimensions */
|
VIDEO_GET_SIZE, /* Get the video dimensions */
|
||||||
VIDEO_PRINT_FRAME, /* Print the frame at the current position */
|
VIDEO_PRINT_FRAME, /* Print the frame at the current position */
|
||||||
VIDEO_PRINT_THUMBNAIL, /* Print a thumbnail of the current position */
|
VIDEO_PRINT_THUMBNAIL, /* Print a thumbnail of the current position */
|
||||||
|
VIDEO_SET_CLIP_RECT, /* Set the visible video area */
|
||||||
#ifdef GRAY_CACHE_MAINT
|
#ifdef GRAY_CACHE_MAINT
|
||||||
VIDEO_GRAY_CACHEOP,
|
VIDEO_GRAY_CACHEOP,
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -24,6 +24,16 @@
|
||||||
#ifndef VIDEO_OUT_H
|
#ifndef VIDEO_OUT_H
|
||||||
#define VIDEO_OUT_H
|
#define VIDEO_OUT_H
|
||||||
|
|
||||||
|
#if LCD_WIDTH >= LCD_HEIGHT
|
||||||
|
#define SCREEN_WIDTH LCD_WIDTH
|
||||||
|
#define SCREEN_HEIGHT LCD_HEIGHT
|
||||||
|
#define LCD_LANDSCAPE
|
||||||
|
#else /* Assume the screen is rotated on portrait LCDs */
|
||||||
|
#define SCREEN_WIDTH LCD_HEIGHT
|
||||||
|
#define SCREEN_HEIGHT LCD_WIDTH
|
||||||
|
#define LCD_PORTRAIT
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Structure to hold width and height values */
|
/* Structure to hold width and height values */
|
||||||
struct vo_ext
|
struct vo_ext
|
||||||
{
|
{
|
||||||
|
@ -43,9 +53,18 @@ bool vo_init (void);
|
||||||
bool vo_show (bool show);
|
bool vo_show (bool show);
|
||||||
bool vo_is_visible(void);
|
bool vo_is_visible(void);
|
||||||
void vo_setup (const mpeg2_sequence_t * sequence);
|
void vo_setup (const mpeg2_sequence_t * sequence);
|
||||||
|
void vo_set_clip_rect(const struct vo_rect *rc);
|
||||||
void vo_dimensions(struct vo_ext *sz);
|
void vo_dimensions(struct vo_ext *sz);
|
||||||
void vo_cleanup (void);
|
void vo_cleanup (void);
|
||||||
|
|
||||||
|
#if NUM_CORES > 1 || !defined (HAVE_LCD_COLOR)
|
||||||
|
void vo_lock(void);
|
||||||
|
void vo_unlock(void);
|
||||||
|
#else
|
||||||
|
static inline void vo_lock(void) {}
|
||||||
|
static inline void vo_unlock(void) {}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Sets all coordinates of a vo_rect to 0 */
|
/* Sets all coordinates of a vo_rect to 0 */
|
||||||
void vo_rect_clear(struct vo_rect *rc);
|
void vo_rect_clear(struct vo_rect *rc);
|
||||||
/* Returns true if left >= right or top >= bottom */
|
/* Returns true if left >= right or top >= bottom */
|
||||||
|
@ -68,4 +87,10 @@ bool vo_rect_intersect(struct vo_rect *rc_dst,
|
||||||
const struct vo_rect *rc1,
|
const struct vo_rect *rc1,
|
||||||
const struct vo_rect *rc2);
|
const struct vo_rect *rc2);
|
||||||
|
|
||||||
|
bool vo_rect_union(struct vo_rect *rc_dst,
|
||||||
|
const struct vo_rect *rc1,
|
||||||
|
const struct vo_rect *rc2);
|
||||||
|
|
||||||
|
void vo_rect_offset(struct vo_rect *rc, int dx, int dy);
|
||||||
|
|
||||||
#endif /* VIDEO_OUT_H */
|
#endif /* VIDEO_OUT_H */
|
||||||
|
|
|
@ -21,6 +21,9 @@
|
||||||
#include "plugin.h"
|
#include "plugin.h"
|
||||||
#include "mpegplayer.h"
|
#include "mpegplayer.h"
|
||||||
|
|
||||||
|
#define VO_NON_NULL_RECT 0x1
|
||||||
|
#define VO_VISIBLE 0x2
|
||||||
|
|
||||||
struct vo_data
|
struct vo_data
|
||||||
{
|
{
|
||||||
int image_width;
|
int image_width;
|
||||||
|
@ -34,8 +37,9 @@ struct vo_data
|
||||||
int output_width;
|
int output_width;
|
||||||
int output_height;
|
int output_height;
|
||||||
bool visible;
|
bool visible;
|
||||||
bool thumb_mode;
|
unsigned flags;
|
||||||
void *last;
|
struct vo_rect rc_vid;
|
||||||
|
struct vo_rect rc_clip;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef PROC_NEEDS_CACHEALIGN
|
#ifdef PROC_NEEDS_CACHEALIGN
|
||||||
|
@ -48,10 +52,40 @@ static uint8_t __vo_data[CACHEALIGN_UP(sizeof(struct vo_data))]
|
||||||
static struct vo_data vo;
|
static struct vo_data vo;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if NUM_CORES > 1
|
||||||
|
static struct mutex vo_mtx NOCACHEBSS_ATTR;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static inline void video_lock_init(void)
|
||||||
|
{
|
||||||
|
#if NUM_CORES > 1
|
||||||
|
rb->mutex_init(&vo_mtx);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void video_lock(void)
|
||||||
|
{
|
||||||
|
#if NUM_CORES > 1
|
||||||
|
rb->mutex_lock(&vo_mtx);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void video_unlock(void)
|
||||||
|
{
|
||||||
|
#if NUM_CORES > 1
|
||||||
|
rb->mutex_unlock(&vo_mtx);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Draw a black rectangle if no video frame is available */
|
/* Draw a black rectangle if no video frame is available */
|
||||||
static void vo_draw_black(void)
|
static void vo_draw_black(void)
|
||||||
{
|
{
|
||||||
int foreground = lcd_(get_foreground)();
|
int foreground;
|
||||||
|
|
||||||
|
video_lock();
|
||||||
|
|
||||||
|
foreground = lcd_(get_foreground)();
|
||||||
|
|
||||||
lcd_(set_foreground)(DRAW_BLACK);
|
lcd_(set_foreground)(DRAW_BLACK);
|
||||||
|
|
||||||
|
@ -61,21 +95,27 @@ static void vo_draw_black(void)
|
||||||
vo.output_height);
|
vo.output_height);
|
||||||
|
|
||||||
lcd_(set_foreground)(foreground);
|
lcd_(set_foreground)(foreground);
|
||||||
|
|
||||||
|
video_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void yuv_blit(uint8_t * const * buf, int src_x, int src_y,
|
static inline void yuv_blit(uint8_t * const * buf, int src_x, int src_y,
|
||||||
int stride, int x, int y, int width, int height)
|
int stride, int x, int y, int width, int height)
|
||||||
{
|
{
|
||||||
|
video_lock();
|
||||||
|
|
||||||
#ifdef HAVE_LCD_COLOR
|
#ifdef HAVE_LCD_COLOR
|
||||||
rb->lcd_yuv_blit(buf, src_x, src_y, stride, x, y , width, height);
|
rb->lcd_yuv_blit(buf, src_x, src_y, stride, x, y , width, height);
|
||||||
#else
|
#else
|
||||||
gray_ub_gray_bitmap_part(buf[0], src_x, src_y, stride, x, y, width, height);
|
gray_ub_gray_bitmap_part(buf[0], src_x, src_y, stride, x, y, width, height);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
video_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void vo_draw_frame(uint8_t * const * buf)
|
void vo_draw_frame(uint8_t * const * buf)
|
||||||
{
|
{
|
||||||
if (!vo.visible)
|
if (vo.flags == 0)
|
||||||
{
|
{
|
||||||
/* Frame is hidden - copout */
|
/* Frame is hidden - copout */
|
||||||
DEBUGF("vo hidden\n");
|
DEBUGF("vo hidden\n");
|
||||||
|
@ -94,14 +134,6 @@ void vo_draw_frame(uint8_t * const * buf)
|
||||||
vo.output_height);
|
vo.output_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LCD_WIDTH >= LCD_HEIGHT
|
|
||||||
#define SCREEN_WIDTH LCD_WIDTH
|
|
||||||
#define SCREEN_HEIGHT LCD_HEIGHT
|
|
||||||
#else /* Assume the screen is rotated on portrait LCDs */
|
|
||||||
#define SCREEN_WIDTH LCD_HEIGHT
|
|
||||||
#define SCREEN_HEIGHT LCD_WIDTH
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline void vo_rect_clear_inl(struct vo_rect *rc)
|
static inline void vo_rect_clear_inl(struct vo_rect *rc)
|
||||||
{
|
{
|
||||||
rc->l = rc->t = rc->r = rc->b = 0;
|
rc->l = rc->t = rc->r = rc->b = 0;
|
||||||
|
@ -172,6 +204,48 @@ bool vo_rect_intersect(struct vo_rect *rc_dst,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool vo_rect_union(struct vo_rect *rc_dst,
|
||||||
|
const struct vo_rect *rc1,
|
||||||
|
const struct vo_rect *rc2)
|
||||||
|
{
|
||||||
|
if (rc_dst != NULL)
|
||||||
|
{
|
||||||
|
if (!vo_rect_empty_inl(rc1))
|
||||||
|
{
|
||||||
|
if (!vo_rect_empty_inl(rc2))
|
||||||
|
{
|
||||||
|
rc_dst->l = MIN(rc1->l, rc2->l);
|
||||||
|
rc_dst->t = MIN(rc1->t, rc2->t);
|
||||||
|
rc_dst->r = MAX(rc1->r, rc2->r);
|
||||||
|
rc_dst->b = MAX(rc1->b, rc2->b);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*rc_dst = *rc1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (!vo_rect_empty(rc2))
|
||||||
|
{
|
||||||
|
*rc_dst = *rc2;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
vo_rect_clear_inl(rc_dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vo_rect_offset(struct vo_rect *rc, int dx, int dy)
|
||||||
|
{
|
||||||
|
rc->l += dx;
|
||||||
|
rc->t += dy;
|
||||||
|
rc->r += dx;
|
||||||
|
rc->b += dy;
|
||||||
|
}
|
||||||
|
|
||||||
/* Shink or stretch each axis - rotate counter-clockwise to retain upright
|
/* Shink or stretch each axis - rotate counter-clockwise to retain upright
|
||||||
* orientation on rotated displays (they rotate clockwise) */
|
* orientation on rotated displays (they rotate clockwise) */
|
||||||
void stretch_image_plane(const uint8_t * src, uint8_t *dst, int stride,
|
void stretch_image_plane(const uint8_t * src, uint8_t *dst, int stride,
|
||||||
|
@ -350,25 +424,27 @@ void vo_setup(const mpeg2_sequence_t * sequence)
|
||||||
|
|
||||||
if (sequence->display_width >= SCREEN_WIDTH)
|
if (sequence->display_width >= SCREEN_WIDTH)
|
||||||
{
|
{
|
||||||
vo.output_width = SCREEN_WIDTH;
|
vo.rc_vid.l = 0;
|
||||||
vo.output_x = 0;
|
vo.rc_vid.r = SCREEN_WIDTH;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vo.output_width = sequence->display_width;
|
vo.rc_vid.l = (SCREEN_WIDTH - sequence->display_width) / 2;
|
||||||
vo.output_x = (SCREEN_WIDTH - sequence->display_width) / 2;
|
vo.rc_vid.r = vo.rc_vid.l + sequence->display_width;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sequence->display_height >= SCREEN_HEIGHT)
|
if (sequence->display_height >= SCREEN_HEIGHT)
|
||||||
{
|
{
|
||||||
vo.output_height = SCREEN_HEIGHT;
|
vo.rc_vid.t = 0;
|
||||||
vo.output_y = 0;
|
vo.rc_vid.b = SCREEN_HEIGHT;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vo.output_height = sequence->display_height;
|
vo.rc_vid.t = (SCREEN_HEIGHT - sequence->display_height) / 2;
|
||||||
vo.output_y = (SCREEN_HEIGHT - sequence->display_height) / 2;
|
vo.rc_vid.b = vo.rc_vid.t + sequence->display_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vo_set_clip_rect(&vo.rc_clip);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vo_dimensions(struct vo_ext *sz)
|
void vo_dimensions(struct vo_ext *sz)
|
||||||
|
@ -379,23 +455,68 @@ void vo_dimensions(struct vo_ext *sz)
|
||||||
|
|
||||||
bool vo_init(void)
|
bool vo_init(void)
|
||||||
{
|
{
|
||||||
vo.visible = false;
|
vo.flags = 0;
|
||||||
|
vo_rect_set_ext(&vo.rc_clip, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
|
||||||
|
video_lock_init();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool vo_show(bool show)
|
bool vo_show(bool show)
|
||||||
{
|
{
|
||||||
bool vis = vo.visible;
|
bool vis = vo.flags & VO_VISIBLE;
|
||||||
vo.visible = show;
|
|
||||||
|
if (show)
|
||||||
|
vo.flags |= VO_VISIBLE;
|
||||||
|
else
|
||||||
|
vo.flags &= ~VO_VISIBLE;
|
||||||
|
|
||||||
return vis;
|
return vis;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool vo_is_visible(void)
|
bool vo_is_visible(void)
|
||||||
{
|
{
|
||||||
return vo.visible;
|
return vo.flags & VO_VISIBLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void vo_cleanup(void)
|
void vo_cleanup(void)
|
||||||
{
|
{
|
||||||
vo.visible = false;
|
vo.flags = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void vo_set_clip_rect(const struct vo_rect *rc)
|
||||||
|
{
|
||||||
|
struct vo_rect rc_out;
|
||||||
|
|
||||||
|
if (rc == NULL)
|
||||||
|
vo_rect_set_ext(&vo.rc_clip, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
|
||||||
|
else
|
||||||
|
vo.rc_clip = *rc;
|
||||||
|
|
||||||
|
if (!vo_rect_intersect(&rc_out, &vo.rc_vid, &vo.rc_clip))
|
||||||
|
vo.flags &= ~VO_NON_NULL_RECT;
|
||||||
|
else
|
||||||
|
vo.flags |= VO_NON_NULL_RECT;
|
||||||
|
|
||||||
|
vo.output_x = rc_out.l;
|
||||||
|
vo.output_y = rc_out.t;
|
||||||
|
vo.output_width = rc_out.r - rc_out.l;
|
||||||
|
vo.output_height = rc_out.b - rc_out.t;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if NUM_CORES > 1 || !defined (HAVE_LCD_COLOR)
|
||||||
|
void vo_lock(void)
|
||||||
|
{
|
||||||
|
#ifndef HAVE_LCD_COLOR
|
||||||
|
set_irq_level(HIGHEST_IRQ_LEVEL);
|
||||||
|
#endif
|
||||||
|
video_lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void vo_unlock(void)
|
||||||
|
{
|
||||||
|
video_unlock();
|
||||||
|
#ifndef HAVE_LCD_COLOR
|
||||||
|
set_irq_level(0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -75,7 +75,10 @@ static void draw_fps(struct video_thread_data *td)
|
||||||
fps / 100, fps % 100, td->num_skipped,
|
fps / 100, fps % 100, td->num_skipped,
|
||||||
td->info->display_picture->temporal_reference);
|
td->info->display_picture->temporal_reference);
|
||||||
rb->lcd_putsxy(0, 0, str);
|
rb->lcd_putsxy(0, 0, str);
|
||||||
|
|
||||||
|
vo_lock();
|
||||||
rb->lcd_update_rect(0, 0, LCD_WIDTH, 8);
|
rb->lcd_update_rect(0, 0, LCD_WIDTH, 8);
|
||||||
|
vo_unlock();
|
||||||
|
|
||||||
td->last_showfps = *rb->current_tick;
|
td->last_showfps = *rb->current_tick;
|
||||||
}
|
}
|
||||||
|
@ -522,7 +525,9 @@ static void video_thread_msg(struct video_thread_data *td)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
IF_COP(invalidate_icache());
|
IF_COP(invalidate_icache());
|
||||||
|
vo_lock();
|
||||||
rb->lcd_update();
|
rb->lcd_update();
|
||||||
|
vo_unlock();
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
GRAY_FLUSH_ICACHE();
|
GRAY_FLUSH_ICACHE();
|
||||||
|
@ -580,6 +585,10 @@ static void video_thread_msg(struct video_thread_data *td)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case VIDEO_SET_CLIP_RECT:
|
||||||
|
vo_set_clip_rect((const struct vo_rect *)td->ev.data);
|
||||||
|
break;
|
||||||
|
|
||||||
case VIDEO_PRINT_FRAME:
|
case VIDEO_PRINT_FRAME:
|
||||||
/* Print the last frame decoded */
|
/* Print the last frame decoded */
|
||||||
if (td->info != NULL && td->info->display_fbuf != NULL)
|
if (td->info != NULL && td->info->display_fbuf != NULL)
|
||||||
|
|
|
@ -359,7 +359,7 @@ void lcd_yuv_blit(unsigned char * const src[3],
|
||||||
#if LCD_WIDTH >= LCD_HEIGHT
|
#if LCD_WIDTH >= LCD_HEIGHT
|
||||||
lcd_update_rect(x, y, width, height);
|
lcd_update_rect(x, y, width, height);
|
||||||
#else
|
#else
|
||||||
lcd_update_rect(y, x, height, width);
|
lcd_update_rect(LCD_WIDTH - y - height, x, height, width);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif /* HAVE_LCD_COLOR */
|
#endif /* HAVE_LCD_COLOR */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue