summaryrefslogtreecommitdiff
path: root/apps/plugins/mpegplayer/video_out_rockbox.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/mpegplayer/video_out_rockbox.c')
-rw-r--r--apps/plugins/mpegplayer/video_out_rockbox.c171
1 files changed, 146 insertions, 25 deletions
diff --git a/apps/plugins/mpegplayer/video_out_rockbox.c b/apps/plugins/mpegplayer/video_out_rockbox.c
index ff0d39eba6..6efbaf0a01 100644
--- a/apps/plugins/mpegplayer/video_out_rockbox.c
+++ b/apps/plugins/mpegplayer/video_out_rockbox.c
@@ -21,6 +21,9 @@
21#include "plugin.h" 21#include "plugin.h"
22#include "mpegplayer.h" 22#include "mpegplayer.h"
23 23
24#define VO_NON_NULL_RECT 0x1
25#define VO_VISIBLE 0x2
26
24struct vo_data 27struct vo_data
25{ 28{
26 int image_width; 29 int image_width;
@@ -34,8 +37,9 @@ struct vo_data
34 int output_width; 37 int output_width;
35 int output_height; 38 int output_height;
36 bool visible; 39 bool visible;
37 bool thumb_mode; 40 unsigned flags;
38 void *last; 41 struct vo_rect rc_vid;
42 struct vo_rect rc_clip;
39}; 43};
40 44
41#ifdef PROC_NEEDS_CACHEALIGN 45#ifdef PROC_NEEDS_CACHEALIGN
@@ -48,10 +52,40 @@ static uint8_t __vo_data[CACHEALIGN_UP(sizeof(struct vo_data))]
48static struct vo_data vo; 52static struct vo_data vo;
49#endif 53#endif
50 54
55#if NUM_CORES > 1
56static struct mutex vo_mtx NOCACHEBSS_ATTR;
57#endif
58
59static inline void video_lock_init(void)
60{
61#if NUM_CORES > 1
62 rb->mutex_init(&vo_mtx);
63#endif
64}
65
66static inline void video_lock(void)
67{
68#if NUM_CORES > 1
69 rb->mutex_lock(&vo_mtx);
70#endif
71}
72
73static inline void video_unlock(void)
74{
75#if NUM_CORES > 1
76 rb->mutex_unlock(&vo_mtx);
77#endif
78}
79
80
51/* Draw a black rectangle if no video frame is available */ 81/* Draw a black rectangle if no video frame is available */
52static void vo_draw_black(void) 82static void vo_draw_black(void)
53{ 83{
54 int foreground = lcd_(get_foreground)(); 84 int foreground;
85
86 video_lock();
87
88 foreground = lcd_(get_foreground)();
55 89
56 lcd_(set_foreground)(DRAW_BLACK); 90 lcd_(set_foreground)(DRAW_BLACK);
57 91
@@ -61,21 +95,27 @@ static void vo_draw_black(void)
61 vo.output_height); 95 vo.output_height);
62 96
63 lcd_(set_foreground)(foreground); 97 lcd_(set_foreground)(foreground);
98
99 video_unlock();
64} 100}
65 101
66static inline void yuv_blit(uint8_t * const * buf, int src_x, int src_y, 102static inline void yuv_blit(uint8_t * const * buf, int src_x, int src_y,
67 int stride, int x, int y, int width, int height) 103 int stride, int x, int y, int width, int height)
68{ 104{
105 video_lock();
106
69#ifdef HAVE_LCD_COLOR 107#ifdef HAVE_LCD_COLOR
70 rb->lcd_yuv_blit(buf, src_x, src_y, stride, x, y , width, height); 108 rb->lcd_yuv_blit(buf, src_x, src_y, stride, x, y , width, height);
71#else 109#else
72 gray_ub_gray_bitmap_part(buf[0], src_x, src_y, stride, x, y, width, height); 110 gray_ub_gray_bitmap_part(buf[0], src_x, src_y, stride, x, y, width, height);
73#endif 111#endif
112
113 video_unlock();
74} 114}
75 115
76void vo_draw_frame(uint8_t * const * buf) 116void vo_draw_frame(uint8_t * const * buf)
77{ 117{
78 if (!vo.visible) 118 if (vo.flags == 0)
79 { 119 {
80 /* Frame is hidden - copout */ 120 /* Frame is hidden - copout */
81 DEBUGF("vo hidden\n"); 121 DEBUGF("vo hidden\n");
@@ -94,14 +134,6 @@ void vo_draw_frame(uint8_t * const * buf)
94 vo.output_height); 134 vo.output_height);
95} 135}
96 136
97#if LCD_WIDTH >= LCD_HEIGHT
98#define SCREEN_WIDTH LCD_WIDTH
99#define SCREEN_HEIGHT LCD_HEIGHT
100#else /* Assume the screen is rotated on portrait LCDs */
101#define SCREEN_WIDTH LCD_HEIGHT
102#define SCREEN_HEIGHT LCD_WIDTH
103#endif
104
105static inline void vo_rect_clear_inl(struct vo_rect *rc) 137static inline void vo_rect_clear_inl(struct vo_rect *rc)
106{ 138{
107 rc->l = rc->t = rc->r = rc->b = 0; 139 rc->l = rc->t = rc->r = rc->b = 0;
@@ -172,6 +204,48 @@ bool vo_rect_intersect(struct vo_rect *rc_dst,
172 return false; 204 return false;
173} 205}
174 206
207bool vo_rect_union(struct vo_rect *rc_dst,
208 const struct vo_rect *rc1,
209 const struct vo_rect *rc2)
210{
211 if (rc_dst != NULL)
212 {
213 if (!vo_rect_empty_inl(rc1))
214 {
215 if (!vo_rect_empty_inl(rc2))
216 {
217 rc_dst->l = MIN(rc1->l, rc2->l);
218 rc_dst->t = MIN(rc1->t, rc2->t);
219 rc_dst->r = MAX(rc1->r, rc2->r);
220 rc_dst->b = MAX(rc1->b, rc2->b);
221 }
222 else
223 {
224 *rc_dst = *rc1;
225 }
226
227 return true;
228 }
229 else if (!vo_rect_empty(rc2))
230 {
231 *rc_dst = *rc2;
232 return true;
233 }
234
235 vo_rect_clear_inl(rc_dst);
236 }
237
238 return false;
239}
240
241void vo_rect_offset(struct vo_rect *rc, int dx, int dy)
242{
243 rc->l += dx;
244 rc->t += dy;
245 rc->r += dx;
246 rc->b += dy;
247}
248
175/* Shink or stretch each axis - rotate counter-clockwise to retain upright 249/* Shink or stretch each axis - rotate counter-clockwise to retain upright
176 * orientation on rotated displays (they rotate clockwise) */ 250 * orientation on rotated displays (they rotate clockwise) */
177void stretch_image_plane(const uint8_t * src, uint8_t *dst, int stride, 251void stretch_image_plane(const uint8_t * src, uint8_t *dst, int stride,
@@ -350,25 +424,27 @@ void vo_setup(const mpeg2_sequence_t * sequence)
350 424
351 if (sequence->display_width >= SCREEN_WIDTH) 425 if (sequence->display_width >= SCREEN_WIDTH)
352 { 426 {
353 vo.output_width = SCREEN_WIDTH; 427 vo.rc_vid.l = 0;
354 vo.output_x = 0; 428 vo.rc_vid.r = SCREEN_WIDTH;
355 } 429 }
356 else 430 else
357 { 431 {
358 vo.output_width = sequence->display_width; 432 vo.rc_vid.l = (SCREEN_WIDTH - sequence->display_width) / 2;
359 vo.output_x = (SCREEN_WIDTH - sequence->display_width) / 2; 433 vo.rc_vid.r = vo.rc_vid.l + sequence->display_width;
360 } 434 }
361 435
362 if (sequence->display_height >= SCREEN_HEIGHT) 436 if (sequence->display_height >= SCREEN_HEIGHT)
363 { 437 {
364 vo.output_height = SCREEN_HEIGHT; 438 vo.rc_vid.t = 0;
365 vo.output_y = 0; 439 vo.rc_vid.b = SCREEN_HEIGHT;
366 } 440 }
367 else 441 else
368 { 442 {
369 vo.output_height = sequence->display_height; 443 vo.rc_vid.t = (SCREEN_HEIGHT - sequence->display_height) / 2;
370 vo.output_y = (SCREEN_HEIGHT - sequence->display_height) / 2; 444 vo.rc_vid.b = vo.rc_vid.t + sequence->display_height;
371 } 445 }
446
447 vo_set_clip_rect(&vo.rc_clip);
372} 448}
373 449
374void vo_dimensions(struct vo_ext *sz) 450void vo_dimensions(struct vo_ext *sz)
@@ -379,23 +455,68 @@ void vo_dimensions(struct vo_ext *sz)
379 455
380bool vo_init(void) 456bool vo_init(void)
381{ 457{
382 vo.visible = false; 458 vo.flags = 0;
459 vo_rect_set_ext(&vo.rc_clip, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
460 video_lock_init();
383 return true; 461 return true;
384} 462}
385 463
386bool vo_show(bool show) 464bool vo_show(bool show)
387{ 465{
388 bool vis = vo.visible; 466 bool vis = vo.flags & VO_VISIBLE;
389 vo.visible = show; 467
468 if (show)
469 vo.flags |= VO_VISIBLE;
470 else
471 vo.flags &= ~VO_VISIBLE;
472
390 return vis; 473 return vis;
391} 474}
392 475
393bool vo_is_visible(void) 476bool vo_is_visible(void)
394{ 477{
395 return vo.visible; 478 return vo.flags & VO_VISIBLE;
396} 479}
397 480
398void vo_cleanup(void) 481void vo_cleanup(void)
399{ 482{
400 vo.visible = false; 483 vo.flags = 0;
401} 484}
485
486void vo_set_clip_rect(const struct vo_rect *rc)
487{
488 struct vo_rect rc_out;
489
490 if (rc == NULL)
491 vo_rect_set_ext(&vo.rc_clip, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
492 else
493 vo.rc_clip = *rc;
494
495 if (!vo_rect_intersect(&rc_out, &vo.rc_vid, &vo.rc_clip))
496 vo.flags &= ~VO_NON_NULL_RECT;
497 else
498 vo.flags |= VO_NON_NULL_RECT;
499
500 vo.output_x = rc_out.l;
501 vo.output_y = rc_out.t;
502 vo.output_width = rc_out.r - rc_out.l;
503 vo.output_height = rc_out.b - rc_out.t;
504}
505
506#if NUM_CORES > 1 || !defined (HAVE_LCD_COLOR)
507void vo_lock(void)
508{
509#ifndef HAVE_LCD_COLOR
510 set_irq_level(HIGHEST_IRQ_LEVEL);
511#endif
512 video_lock();
513}
514
515void vo_unlock(void)
516{
517 video_unlock();
518#ifndef HAVE_LCD_COLOR
519 set_irq_level(0);
520#endif
521}
522#endif