--- rockbox-bleeding\apps\plugins\mpegplayer\mpegplayer.c 2007-05-19 19:38:22.000000000 -0400 +++ cygwin\home\j\rockbox\apps\plugins\mpegplayer\mpegplayer.c 2007-06-09 17:05:03.302509200 -0400 @@ -167,6 +167,30 @@ static mpeg2dec_t * mpeg2dec; static int total_offset = 0; +static char resumefile[MAX_PATH]; +static uint32_t filestartposition= 0; +static uint32_t filecurrentposition=0; + +static void saveresumeposition(uint32_t savepos) { + int rfd; + + if (savepos<1) + { + return; + } + + rfd = rb->open(resumefile, O_WRONLY|O_CREAT); + if (rfd<0) + { + rb->splash( 100, "Can't open %s for writing!", resumefile ); + rb->sleep(HZ*3); + rb->lcd_clear_display(); + rb->lcd_update(); + } + rb->fdprintf(rfd,"%lu",savepos); + rb->close(rfd); +} + /* Utility */ /* Atomically add one long value to another - not core safe atm if ever needed */ @@ -276,6 +300,7 @@ #define MPA_MAX_FRAME_SIZE 1729 /* Largest frame - MPEG1, Layer II, 384kbps, 32kHz, pad */ #define MPABUF_SIZE (64*1024 + ALIGN_UP(MPA_MAX_FRAME_SIZE + 2*MAD_BUFFER_GUARD, 4)) #define LIBMPEG2BUFFER_SIZE (2*1024*1024) +#define READBLOCK_SIZE (64*1024) /* 65536+6 is required since each PES has a 6 byte header with a 16 bit packet length field */ #define MPEG_GUARDBUF_SIZE (64*1024+1024) /* Keep a bit extra - excessive for now */ @@ -792,7 +817,7 @@ pts_queue_rd = pts_queue_wr; pts = pts_queue_tail(); pts->pts = 0; - pts->size = 0; + pts->size = 0; } struct pcm_frame_header /* Header added to pcm data every time a decoded @@ -1304,6 +1329,7 @@ while (1) { + if (videostatus == PLEASE_STOP) { break; @@ -1324,7 +1350,7 @@ /* Prevent idle poweroff */ rb->reset_poweroff_timer(); - + switch (state) { case STATE_BUFFER: @@ -1393,7 +1419,7 @@ } mpeg2_skip(mpeg2dec, skip); - break; + break; } case STATE_SLICE: @@ -1615,6 +1641,14 @@ uint8_t* buffer; size_t file_remaining; size_t disk_buf_len; + + int button; + uint32_t fileresumeposition; + int resumefilehandle; + char templine[80]; + int resumepercent; + int i; + #ifndef HAVE_LCD_COLOR long graysize; int grayscales; @@ -1687,6 +1721,7 @@ /* Open the video file */ in_file = rb->open((char*)parameter,O_RDONLY); + file_remaining = rb->filesize(in_file); if (in_file < 0){ //fprintf(stderr,"Could not open %s\n",argv[1]); @@ -1713,13 +1748,82 @@ #ifdef HAVE_ADJUSTABLE_CPU_FREQ rb->cpu_boost(true); #endif + /* Establish the name to be used for the resume data */ + rb->snprintf(resumefile,sizeof(resumefile),"%s.resume",(char*)parameter); - /* From this point on we've altered settings, colors, cpu_boost, etc. and + /* From this point on we've altered settings, colors, cpu_boost, etc. and cannot just return PLUGIN_ERROR - instead drop though to cleanup code */ - init_settings(); + if (settings.resume!=0) + { + /* Open the resume file if present*/ + resumefilehandle = rb->open(resumefile,O_RDONLY); + + if (resumefilehandle > -1) + { + rb->read_line(resumefilehandle, templine, sizeof(templine)); + filestartposition=rb->atoi(templine); + } + rb->close(resumefilehandle); + /* delete existing resume file */ + rb->remove(resumefile); + + if (filestartposition>0) + { + resumepercent=(int)(filestartposition/(file_remaining/100)); + if (settings.resume==2) + { + if (resumepercent>0) + { + rb->snprintf(templine,sizeof(templine),"Resume playback at %d%%?",resumepercent); + } + else + { + rb->snprintf(templine,sizeof(templine),"Resume playback at <1%%?"); + } + + FOR_NB_SCREENS(i) + { + rb->screens[i]->clear_display(); + rb->screens[i]->putsxy(0,40, templine); + rb->screens[i]->putsxy(0,70, "Press SELECT to resume or"); + rb->screens[i]->putsxy(0,85, "any other key to restart video."); + rb->screens[i]->update(); + } + + button=rb->button_get(true); + switch (button) + { + case MPEG_PAUSE: + break; + + default: + filestartposition=0; + break; + } + } + if (filestartposition==0) + { + rb->splash( 50, "Restarting video..."); + } + else + { + if (resumepercent>0) + { + rb->splash( 50, "Resuming video at %d%%...",resumepercent); + } + else + { + rb->splash( 50, "Resuming video at <1%%..."); + } + } + rb->sleep(HZ*1); + } + } + rb->lcd_clear_display(); + /* Msg queue init - no need for queue_remove since it's not a registered queue */ rb->queue_init( &msg_queue, false ); @@ -1728,11 +1832,18 @@ rb->memset(mad_frame_overlap, 0, sizeof(mad_frame_overlap)); init_mad(mad_frame_overlap); - file_remaining = rb->filesize(in_file); + disk_buf_end = buffer + buffer_size-MPEG_GUARDBUF_SIZE; /* Read some stream data */ - disk_buf_len = rb->read (in_file, buffer, MPEG_LOW_WATERMARK); + disk_buf_len = rb->read (in_file, buffer, READBLOCK_SIZE); + + if (filestartposition>0) + { + filecurrentposition=rb->lseek(in_file, filestartposition, SEEK_CUR); + file_remaining -= filestartposition; + } + DEBUGF("Initial Buffering - %d bytes\n",(int)disk_buf_len); disk_buf = buffer; @@ -1769,7 +1880,6 @@ } else { - //DEBUGF("START: video = %d, audio = %d\n",audio_str.buffer_remaining,video_str.buffer_remaining); rb->lcd_setfont(FONT_SYSFIXED); /* Wait until both threads have finished their work */ @@ -1787,25 +1897,26 @@ while (( bytes_to_read > 0) && (file_remaining > 0) && ((audiostatus != STREAM_DONE) || (videostatus != STREAM_DONE))) { - size_t n = rb->read(in_file, disk_buf_tail, MIN(32*1024,bytes_to_read)); - - bytes_to_read -= n; - file_remaining -= n; - lock_stream(); - audio_str.buffer_remaining += n; - video_str.buffer_remaining += n; - unlock_stream(); + size_t n = rb->read(in_file, disk_buf_tail, MIN(32*1024,bytes_to_read)); + + filecurrentposition+=n; + bytes_to_read -= n; + file_remaining -= n; + + lock_stream(); + audio_str.buffer_remaining += n; + video_str.buffer_remaining += n; + unlock_stream(); - disk_buf_tail += n; + disk_buf_tail += n; - rb->yield(); + rb->yield(); } if (disk_buf_tail == disk_buf_end) disk_buf_tail = buffer; } - rb->sleep(HZ/10); } @@ -1845,6 +1956,18 @@ rb->cpu_boost(false); #endif + if ((video_str.curr_packet==NULL) || (audio_str.curr_packet==NULL)) + { + rb->splash(50,"* End of video *"); + rb->sleep(HZ*1); + } + else + { + fileresumeposition=((filecurrentposition-video_str.buffer_remaining)/(READBLOCK_SIZE))*(READBLOCK_SIZE); + fileresumeposition-=READBLOCK_SIZE; + saveresumeposition(fileresumeposition); + } + save_settings(); /* Save settings (if they have changed) */ #ifdef HAVE_BACKLIGHT --- rockbox-bleeding\apps\plugins\mpegplayer\mpeg_settings.c 2007-05-08 07:56:38.000000000 -0400 +++ cygwin\home\j\rockbox\apps\plugins\mpegplayer\mpeg_settings.c 2007-06-01 10:25:28.781250000 -0400 @@ -16,12 +16,16 @@ static char* showfps_options[] = {"No", "Yes"}; static char* limitfps_options[] = {"No", "Yes"}; static char* skipframes_options[] = {"No", "Yes"}; +static char* resume_options[] = {"Never", "Always","Prompt"}; + static struct configdata config[] = { {TYPE_ENUM, 0, 2, &settings.showfps, "Show FPS", showfps_options, NULL}, {TYPE_ENUM, 0, 2, &settings.limitfps, "Limit FPS", limitfps_options, NULL}, {TYPE_ENUM, 0, 2, &settings.skipframes, "Skip frames", skipframes_options, NULL}, + {TYPE_ENUM, 0, 3, &settings.resume, "Resume video", resume_options, NULL}, + }; bool mpeg_menu(void) @@ -35,10 +39,17 @@ { "Yes", -1 }, }; + static const struct opt_items noyesprompt[3] = { + { "Never", -1 }, + { "Always", -1 }, + { "Prompt", -1 }, + }; + static const struct menu_item items[] = { { "Display FPS", NULL }, { "Limit FPS", NULL }, { "Skip frames", NULL }, + { "Resume video", NULL }, { "Quit mpegplayer", NULL }, }; @@ -64,10 +75,14 @@ rb->set_option("Skip frames",&settings.skipframes,INT, noyes, 2, NULL); break; + case 3: /* Resume video */ + rb->set_option("Resume video",&settings.resume,INT, + noyesprompt, 3, NULL); + break; default: menu_quit=1; if (result == MENU_ATTACHED_USB) - result = 3; + result = 4; break; } } @@ -77,7 +92,7 @@ rb->lcd_clear_display(); rb->lcd_update(); - return (result==3); + return (result==4); } @@ -87,6 +102,7 @@ settings.showfps = 0; /* Do not show FPS */ settings.limitfps = 1; /* Limit FPS */ settings.skipframes = 1; /* Skip frames */ + settings.resume = 2; /* Resume video - PROMPT */ configfile_init(rb); --- rockbox-bleeding\apps\plugins\mpegplayer\mpeg_settings.h 2007-01-09 16:34:26.000000000 -0500 +++ cygwin\home\j\rockbox\apps\plugins\mpegplayer\mpeg_settings.h 2007-06-01 09:35:00.921875000 -0400 @@ -5,6 +5,7 @@ int showfps; int limitfps; int skipframes; + int resume; }; extern struct mpeg_settings settings;