diff options
Diffstat (limited to 'apps/plugins/video.c')
-rw-r--r-- | apps/plugins/video.c | 106 |
1 files changed, 66 insertions, 40 deletions
diff --git a/apps/plugins/video.c b/apps/plugins/video.c index 1ba2b89e37..69c6f4ed9e 100644 --- a/apps/plugins/video.c +++ b/apps/plugins/video.c | |||
@@ -178,7 +178,8 @@ static struct | |||
178 | int granularity; /* common multiple of block and sector size */ | 178 | int granularity; /* common multiple of block and sector size */ |
179 | unsigned char* pBufStart; /* start of ring buffer */ | 179 | unsigned char* pBufStart; /* start of ring buffer */ |
180 | unsigned char* pBufEnd; /* end of ring buffer */ | 180 | unsigned char* pBufEnd; /* end of ring buffer */ |
181 | unsigned char* pOSD; /* OSD memory (112 bytes for 112*8 pixels) */ | 181 | int osd_ypos; |
182 | int osd_height; | ||
182 | 183 | ||
183 | int vidcount; /* how many video blocks are known in a row */ | 184 | int vidcount; /* how many video blocks are known in a row */ |
184 | unsigned char* pBufFill; /* write pointer for disk, owned by main task */ | 185 | unsigned char* pBufFill; /* write pointer for disk, owned by main task */ |
@@ -219,22 +220,29 @@ int Available(unsigned char* pSnapshot) | |||
219 | /* debug function to draw buffer indicators */ | 220 | /* debug function to draw buffer indicators */ |
220 | void DrawBuf(void) | 221 | void DrawBuf(void) |
221 | { | 222 | { |
222 | int fill, video, audio; | 223 | int ypos, fill, video, audio; |
223 | 224 | ||
224 | rb->memset(gBuf.pOSD, 0x10, LCD_WIDTH); /* draw line */ | 225 | rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); |
225 | gBuf.pOSD[0] = gBuf.pOSD[LCD_WIDTH-1] = 0xFE; /* ends */ | 226 | rb->lcd_fillrect(0, gBuf.osd_ypos, LCD_WIDTH, gBuf.osd_height); |
227 | rb->lcd_set_drawmode(DRMODE_SOLID); | ||
228 | |||
229 | ypos = gBuf.osd_ypos + gBuf.osd_height/2 - 3; /* center vertically */ | ||
230 | |||
231 | rb->lcd_hline(1, LCD_WIDTH-2, ypos + 3); | ||
232 | rb->lcd_vline(0, ypos, ypos + 6); | ||
233 | rb->lcd_vline(LCD_WIDTH-1, ypos, ypos + 6); | ||
226 | 234 | ||
227 | /* calculate new tick positions */ | 235 | /* calculate new tick positions */ |
228 | fill = 1 + ((gBuf.pBufFill - gBuf.pBufStart) * (LCD_WIDTH-2)) / gBuf.bufsize; | 236 | fill = 1 + ((gBuf.pBufFill - gBuf.pBufStart) * (LCD_WIDTH-2)) / gBuf.bufsize; |
229 | video = 1 + ((gBuf.pReadVideo - gBuf.pBufStart) * (LCD_WIDTH-2)) / gBuf.bufsize; | 237 | video = 1 + ((gBuf.pReadVideo - gBuf.pBufStart) * (LCD_WIDTH-2)) / gBuf.bufsize; |
230 | audio = 1 + ((gBuf.pReadAudio - gBuf.pBufStart) * (LCD_WIDTH-2)) / gBuf.bufsize; | 238 | audio = 1 + ((gBuf.pReadAudio - gBuf.pBufStart) * (LCD_WIDTH-2)) / gBuf.bufsize; |
231 | 239 | ||
232 | gBuf.pOSD[fill] |= 0x20; /* below the line, two pixels */ | 240 | rb->lcd_drawpixel(fill, ypos + 4); |
233 | gBuf.pOSD[video] |= 0x08; /* one above */ | 241 | rb->lcd_drawpixel(video, ypos + 2); |
234 | gBuf.pOSD[audio] |= 0x04; /* two above */ | 242 | rb->lcd_drawpixel(audio, ypos + 1); |
235 | 243 | ||
236 | if (gPlay.state == paused) /* we have to draw ourselves */ | 244 | if (gPlay.state == paused) /* we have to draw ourselves */ |
237 | rb->lcd_update_rect(0, LCD_HEIGHT-8, LCD_WIDTH, 8); | 245 | rb->lcd_update_rect(0, gBuf.osd_ypos, LCD_WIDTH, gBuf.osd_height); |
238 | else | 246 | else |
239 | gPlay.bDirtyOSD = true; /* redraw it with next timer IRQ */ | 247 | gPlay.bDirtyOSD = true; /* redraw it with next timer IRQ */ |
240 | } | 248 | } |
@@ -243,33 +251,60 @@ void DrawBuf(void) | |||
243 | /* helper function to draw a position indicator */ | 251 | /* helper function to draw a position indicator */ |
244 | void DrawPosition(int pos, int total) | 252 | void DrawPosition(int pos, int total) |
245 | { | 253 | { |
246 | int w,h; | 254 | int w, h; |
247 | int sec; /* estimated seconds */ | 255 | int sec; /* estimated seconds */ |
256 | int ypos; | ||
248 | 257 | ||
258 | rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); | ||
259 | rb->lcd_fillrect(0, gBuf.osd_ypos, LCD_WIDTH, gBuf.osd_height); | ||
260 | rb->lcd_set_drawmode(DRMODE_SOLID); | ||
249 | 261 | ||
250 | /* print the estimated position */ | 262 | /* print the estimated position */ |
251 | sec = pos / (gFileHdr.bps_average/8); | 263 | sec = pos / (gFileHdr.bps_average/8); |
252 | if (sec < 100*60) /* fits into mm:ss format */ | 264 | if (sec < 100*60) /* fits into mm:ss format */ |
253 | rb->snprintf(gPrint, sizeof(gPrint), "%02d:%02dm", sec/60, sec%60); | 265 | rb->snprintf(gPrint, sizeof(gPrint), "%02d:%02dm", sec/60, sec%60); |
254 | else /* a very long clip, hh:mm format */ | 266 | else /* a very long clip, hh:mm format */ |
255 | rb->snprintf(gPrint, sizeof(gPrint), "%02d:%02dh", sec/3600, (sec/60)%60); | 267 | rb->snprintf(gPrint, sizeof(gPrint), "%02d:%02dh", sec/3600, (sec/60)%60); |
256 | rb->lcd_puts(0, 7, gPrint); | ||
257 | 268 | ||
258 | /* draw a slider over the rest of the line */ | ||
259 | rb->lcd_getstringsize(gPrint, &w, &h); | 269 | rb->lcd_getstringsize(gPrint, &w, &h); |
260 | w++; | 270 | w++; |
261 | rb->gui_scrollbar_draw(rb->screens[SCREEN_MAIN],w, LCD_HEIGHT-7, LCD_WIDTH-w, | 271 | ypos = gBuf.osd_ypos + (gBuf.osd_height - h) / 2; |
262 | 7, total, 0, pos, HORIZONTAL); | 272 | rb->lcd_putsxy(0, ypos, gPrint); |
273 | |||
274 | /* draw a slider over the rest of the line */ | ||
275 | rb->gui_scrollbar_draw(rb->screens[SCREEN_MAIN], w, ypos, LCD_WIDTH-w, | ||
276 | h, total, 0, pos, HORIZONTAL); | ||
263 | 277 | ||
264 | if (gPlay.state == paused) /* we have to draw ourselves */ | 278 | if (gPlay.state == paused) /* we have to draw ourselves */ |
265 | rb->lcd_update_rect(0, LCD_HEIGHT-8, LCD_WIDTH, 8); | 279 | rb->lcd_update_rect(0, gBuf.osd_ypos, LCD_WIDTH, gBuf.osd_height); |
266 | else /* let the display time do it */ | 280 | else /* let the display time do it */ |
267 | { | 281 | { |
268 | gPlay.nTimeOSD = 70; | 282 | gPlay.nTimeOSD = FPS; |
269 | gPlay.bDirtyOSD = true; /* redraw it with next timer IRQ */ | 283 | gPlay.bDirtyOSD = true; /* redraw it with next timer IRQ */ |
270 | } | 284 | } |
271 | } | 285 | } |
272 | 286 | ||
287 | /* Put text on OSD and activate it for 1 second */ | ||
288 | void osd_show_text(void) | ||
289 | { | ||
290 | int h, ypos; | ||
291 | |||
292 | rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); | ||
293 | rb->lcd_fillrect(0, gBuf.osd_ypos, LCD_WIDTH, gBuf.osd_height); | ||
294 | rb->lcd_set_drawmode(DRMODE_SOLID); | ||
295 | |||
296 | rb->lcd_getstringsize(gPrint, NULL, &h); | ||
297 | ypos = gBuf.osd_ypos + (gBuf.osd_height - h) / 2; | ||
298 | rb->lcd_putsxy(0, ypos, gPrint); | ||
299 | |||
300 | if (gPlay.state == paused) /* we have to draw ourselves */ | ||
301 | rb->lcd_update_rect(0, gBuf.osd_ypos, LCD_WIDTH, gBuf.osd_height); | ||
302 | else /* let the display time do it */ | ||
303 | { | ||
304 | gPlay.nTimeOSD = FPS; /* display it for 1 sec */ | ||
305 | gPlay.bDirtyOSD = true; /* let the refresh copy it to LCD */ | ||
306 | } | ||
307 | } | ||
273 | 308 | ||
274 | /* helper function to change the volume by a certain amount, +/- */ | 309 | /* helper function to change the volume by a certain amount, +/- */ |
275 | void ChangeVolume(int delta) | 310 | void ChangeVolume(int delta) |
@@ -284,15 +319,9 @@ void ChangeVolume(int delta) | |||
284 | { | 319 | { |
285 | rb->sound_set(SOUND_VOLUME, vol); | 320 | rb->sound_set(SOUND_VOLUME, vol); |
286 | rb->global_settings->volume = vol; | 321 | rb->global_settings->volume = vol; |
322 | |||
287 | rb->snprintf(gPrint, sizeof(gPrint), "Vol: %d dB", vol); | 323 | rb->snprintf(gPrint, sizeof(gPrint), "Vol: %d dB", vol); |
288 | rb->lcd_puts(0, 7, gPrint); | 324 | osd_show_text(); |
289 | if (gPlay.state == paused) /* we have to draw ourselves */ | ||
290 | rb->lcd_update_rect(0, LCD_HEIGHT-8, LCD_WIDTH, 8); | ||
291 | else /* let the display time do it */ | ||
292 | { | ||
293 | gPlay.nTimeOSD = 50; /* display it for 50 frames */ | ||
294 | gPlay.bDirtyOSD = true; /* let the refresh copy it to LCD */ | ||
295 | } | ||
296 | } | 325 | } |
297 | } | 326 | } |
298 | 327 | ||
@@ -313,15 +342,9 @@ void ChangeContrast(int delta) | |||
313 | { | 342 | { |
314 | rb->lcd_set_contrast(contrast); | 343 | rb->lcd_set_contrast(contrast); |
315 | mycontrast = contrast; | 344 | mycontrast = contrast; |
345 | |||
316 | rb->snprintf(gPrint, sizeof(gPrint), "Contrast: %d", contrast); | 346 | rb->snprintf(gPrint, sizeof(gPrint), "Contrast: %d", contrast); |
317 | rb->lcd_puts(0, 7, gPrint); | 347 | osd_show_text(); |
318 | if (gPlay.state == paused) /* we have to draw ourselves */ | ||
319 | rb->lcd_update_rect(0, LCD_HEIGHT-8, LCD_WIDTH, 8); | ||
320 | else /* let the display time do it */ | ||
321 | { | ||
322 | gPlay.nTimeOSD = 50; /* display it for 50 frames */ | ||
323 | gPlay.bDirtyOSD = true; /* let the refresh copy it to LCD */ | ||
324 | } | ||
325 | } | 348 | } |
326 | } | 349 | } |
327 | 350 | ||
@@ -356,21 +379,20 @@ void timer4_isr(void) | |||
356 | int height; /* height to display */ | 379 | int height; /* height to display */ |
357 | 380 | ||
358 | /* reduce height if we have OSD on */ | 381 | /* reduce height if we have OSD on */ |
359 | height = gFileHdr.video_height/8; | 382 | height = gFileHdr.video_height; |
360 | if (gPlay.nTimeOSD > 0) | 383 | if (gPlay.nTimeOSD > 0) |
361 | { | 384 | { |
362 | gPlay.nTimeOSD--; | 385 | gPlay.nTimeOSD--; |
363 | height = MIN(LCD_HEIGHT/8-1, height); /* reserve bottom line */ | 386 | height = MIN(gBuf.osd_ypos, height); |
364 | if (gPlay.bDirtyOSD) | 387 | if (gPlay.bDirtyOSD) |
365 | { /* OSD to bottom line */ | 388 | { |
366 | rb->lcd_blit_mono(gBuf.pOSD, 0, LCD_HEIGHT/8-1, | 389 | rb->lcd_update_rect(0, gBuf.osd_ypos, LCD_WIDTH, gBuf.osd_height); |
367 | LCD_WIDTH, 1, LCD_WIDTH); | ||
368 | gPlay.bDirtyOSD = false; | 390 | gPlay.bDirtyOSD = false; |
369 | } | 391 | } |
370 | } | 392 | } |
371 | 393 | ||
372 | rb->lcd_blit_mono(gBuf.pReadVideo, 0, 0, | 394 | rb->lcd_blit_mono(gBuf.pReadVideo, 0, 0, |
373 | gFileHdr.video_width, height, gFileHdr.video_width); | 395 | gFileHdr.video_width, height/8, gFileHdr.video_width); |
374 | 396 | ||
375 | available = Available(gBuf.pReadVideo); | 397 | available = Available(gBuf.pReadVideo); |
376 | 398 | ||
@@ -776,7 +798,7 @@ int PlayTick(int fd) | |||
776 | case VIDEO_DEBUG: /* debug key */ | 798 | case VIDEO_DEBUG: /* debug key */ |
777 | case VIDEO_DEBUG | BUTTON_REPEAT: | 799 | case VIDEO_DEBUG | BUTTON_REPEAT: |
778 | DrawBuf(); /* show buffer status */ | 800 | DrawBuf(); /* show buffer status */ |
779 | gPlay.nTimeOSD = 30; | 801 | gPlay.nTimeOSD = FPS/2; |
780 | gPlay.bDirtyOSD = true; | 802 | gPlay.bDirtyOSD = true; |
781 | break; | 803 | break; |
782 | #endif | 804 | #endif |
@@ -874,10 +896,14 @@ int main(char* filename) | |||
874 | 896 | ||
875 | /* init buffer */ | 897 | /* init buffer */ |
876 | rb->memset(&gBuf, 0, sizeof(gBuf)); | 898 | rb->memset(&gBuf, 0, sizeof(gBuf)); |
877 | gBuf.pOSD = rb->lcd_framebuffer + LCD_WIDTH*7; /* last screen line */ | ||
878 | gBuf.pBufStart = rb->plugin_get_audio_buffer((size_t *)&gBuf.bufsize); | 899 | gBuf.pBufStart = rb->plugin_get_audio_buffer((size_t *)&gBuf.bufsize); |
879 | /*gBuf.bufsize = 1700*1024; // test, like 2MB version!!!! */ | 900 | /*gBuf.bufsize = 1700*1024; // test, like 2MB version!!!! */ |
880 | gBuf.pBufFill = gBuf.pBufStart; /* all empty */ | 901 | gBuf.pBufFill = gBuf.pBufStart; /* all empty */ |
902 | |||
903 | /* init OSD */ | ||
904 | rb->lcd_getstringsize("X", NULL, &retval); | ||
905 | gBuf.osd_height = (retval + 7) & ~7; | ||
906 | gBuf.osd_ypos = LCD_HEIGHT - gBuf.osd_height; | ||
881 | 907 | ||
882 | /* load file header */ | 908 | /* load file header */ |
883 | read_now = sizeof(gFileHdr); | 909 | read_now = sizeof(gFileHdr); |