sensible-cinema 0.34.0 → 0.35.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. data/.gitmodules +1 -1
  2. data/README.TXT +19 -20
  3. data/Rakefile +191 -195
  4. data/TODO +122 -149
  5. data/VERSION +1 -1
  6. data/bin/sensible-cinema +52 -52
  7. data/change_log_with_feature_list.txt +532 -481
  8. data/documentation/troubleshooting.txt +3 -9
  9. data/go.bat +2 -2
  10. data/go.sh +1 -0
  11. data/goc.bat +1 -1
  12. data/goc.sh +1 -0
  13. data/lib/check_installed_mac.rb +2 -10
  14. data/lib/edl_parser.rb +40 -16
  15. data/lib/gui/base.rb +85 -27
  16. data/lib/gui/create-file.rb +3 -2
  17. data/lib/gui/create.rb +118 -101
  18. data/lib/gui/dependencies.rb +110 -76
  19. data/lib/gui/normal.rb +32 -81
  20. data/lib/mplayer_edl.rb +7 -1
  21. data/lib/subtitle_profanity_finder.rb +10 -5
  22. data/notes_for_potential_developers.txt +18 -25
  23. data/spec/bad_beginning.srt +3778 -0
  24. data/spec/edl_parser.spec.rb +4 -0
  25. data/spec/notes +327 -167
  26. data/spec/youtube_edl.spec.rb +28 -0
  27. data/template_bats/RUN SENSIBLE CINEMA CLICK HERE WINDOWS.bat +2 -2
  28. data/todo.inventionzy.txt +3 -1
  29. data/vendor/mplayer_patches/how_to_doze.bat +6 -0
  30. data/vendor/mplayer_patches/port_dir/PortIndex.quick +1 -1
  31. data/vendor/mplayer_patches/port_dir/how_to +16 -9
  32. data/vendor/mplayer_patches/port_dir/multimedia/mplayer-edl/Portfile +10 -25
  33. data/vendor/mplayer_patches/port_dir/multimedia/rdp-projects/Portfile +2 -2
  34. data/vendor/mplayer_patches/{configure_from_betterlogic → port_dir_is_for_mac} +0 -0
  35. data/www/content_editor.html +9 -5
  36. data/zamples/edit_decision_lists/dvds/big_buck_bunny_dvd.txt +7 -4
  37. data/zamples/edit_decision_lists/dvds/court_jester.txt +0 -1
  38. data/zamples/edit_decision_lists/dvds/edls_being_edited/father_goose.txt +41 -0
  39. data/zamples/edit_decision_lists/dvds/edls_being_edited/harry_potter_and_the_goblet_of_fire.txt +45 -0
  40. data/zamples/edit_decision_lists/dvds/edls_being_edited/national_treasure.txt +6 -3
  41. data/zamples/edit_decision_lists/dvds/edls_being_edited/percy_jackson_lightening_thief.txt +40 -0
  42. data/zamples/edit_decision_lists/dvds/edls_being_edited/percy_jackson_lightening_thief_mute_scary.txt +23 -0
  43. data/zamples/edit_decision_lists/dvds/edls_being_edited/puss_in_boots.txt +33 -0
  44. data/zamples/edit_decision_lists/dvds/edls_being_edited/ratatouille.txt +5 -5
  45. data/zamples/edit_decision_lists/dvds/edls_being_edited/rio.txt +24 -0
  46. data/zamples/edit_decision_lists/dvds/sintel_open_source_blender_ntsc_dvd.txt +0 -1
  47. metadata +17 -15
  48. data/lib/count_down_timer_jruby_swing.rb +0 -55
  49. data/vendor/mplayer_patches/apply.bat +0 -12
  50. data/vendor/mplayer_patches/libdvdnav/2905259c3b45529b3d8dedba572b6e4f67a2d8f4.diff +0 -19
  51. data/vendor/mplayer_patches/libdvdnav/83f1c9256f500285e46f1e44bcc74ffce90159db.diff +0 -16
  52. data/vendor/mplayer_patches/libdvdnav/eb91fb74680d30322461a1b9e425918ad4e2b2df.diff +0 -21
  53. data/vendor/mplayer_patches/libdvdnav/jump_to_time.diff +0 -654
  54. data/vendor/mplayer_patches/libdvdnav/non_strict.diff +0 -13
  55. data/vendor/mplayer_patches/mplayer_edl.diff +0 -354
  56. data/vendor/mplayer_patches/updated_lib_too +0 -0
@@ -6,15 +6,15 @@
6
6
 
7
7
  "1:26:19.09" , "1:26:22.39", "profanity", "bloo..", "and no one else seems to have it in this [bloo..] town,",
8
8
 
9
- "0:03:11.12" , "0:03:12.82", "profanity", "deity", "Close to [deity]liness.",
10
- "0:22:42.52" , "0:22:44.42", "profanity", "deity", "Five minutes, chef. - Oh, [deity].",
9
+ "0:03:11.12" , "0:03:12.82", "profanity", "deity", "Close to [vain use]liness.",
10
+ "0:22:42.52" , "0:22:44.42", "profanity", "deity", "Five minutes, chef. - Oh, [vain use].",
11
11
  "0:35:11.63" , "0:35:17.13", "profanity", "he..", "Welcome to [he..] Now, recreate the soup.",
12
- "0:57:38.29" , "0:57:42.19", "profanity", "deity", "Nothing's been poisoned, thank [deity], but it hasn't been easy.",
12
+ "0:57:38.29" , "0:57:42.19", "profanity", "deity", "Nothing's been poisoned, thank [vain use], but it hasn't been easy.",
13
13
  ],
14
14
 
15
15
  "blank_outs" => [
16
- # an example line, uncomment the leading "#" to make it active
17
- # "00:03:00.0" , "00:04:00.0", "violence", "of some sort",
16
+
17
+ "0:10", "0:15",
18
18
  ],
19
19
 
20
20
  "source" => "dvd",
@@ -0,0 +1,24 @@
1
+ # edl_version_version 1.1, sensible cinema v0.34.0
2
+ # comments can go be created by placing text after a # on any line, for example this one.
3
+ "name" => "Rio",
4
+
5
+ "mutes" => [
6
+ "1:16:51.18", "1:16:51.90", # in portuges
7
+
8
+ ],
9
+
10
+ "blank_outs" => [
11
+ "1:13:12.90", "1:13:21.89", #riske
12
+ ],
13
+
14
+ "source" => "dvd",
15
+ "volume_name" => "RIO",
16
+ "timestamps_relative_to" => ["dvd_start_offset","29.97"],
17
+ "disk_unique_id" => "3b70cf79|a9b792f7",
18
+ "dvd_title_track" => "1", # our guess for it
19
+ "dvd_title_track_length" => "5751.333",
20
+ # "not edited out stuff" => "some...",
21
+ # "closing thoughts" => "only ...",
22
+ # "subtitles_to_display_relative_path" => "some_file.srt" # if you want to display some custom subtitles alongside your movie
23
+ "dvd_title_track_start_offset" => "0.2",
24
+ "dvd_nav_packet_offset" => [0.766667, 0.862967],
@@ -6,7 +6,6 @@
6
6
  "blank_outs" => [
7
7
  "00:00:56.0" , "00:00:57.0", "violence", "knife stabbing",
8
8
  "00:01:05.0" , "00:01:14.5", "violence", "stab through",
9
- "90.0", "100.0", "violence", "test cut",
10
9
  ],
11
10
 
12
11
  "dvd_nav_packet_offset" => [0.5, 0.734067],
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: sensible-cinema
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.34.0
5
+ version: 0.35.3
6
6
  platform: ruby
7
7
  authors:
8
8
  - Roger Pack
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2012-01-17 00:00:00 Z
13
+ date: 2012-04-21 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: os
@@ -31,7 +31,7 @@ dependencies:
31
31
  requirements:
32
32
  - - ">="
33
33
  - !ruby/object:Gem::Version
34
- version: 0.25.2
34
+ version: 0.25.4
35
35
  type: :runtime
36
36
  version_requirements: *id002
37
37
  - !ruby/object:Gem::Dependency
@@ -241,9 +241,11 @@ files:
241
241
  - experimental_online_player_ocr_readme.txt
242
242
  - go
243
243
  - go.bat
244
+ - go.sh
244
245
  - go_ocr_tracker.bat
245
246
  - goc
246
247
  - goc.bat
248
+ - goc.sh
247
249
  - gpl-2.0.txt
248
250
  - gplv3.txt
249
251
  - history_and_related_works_list.txt
@@ -258,7 +260,6 @@ files:
258
260
  - lib/blanker.rb
259
261
  - lib/check_installed_mac.rb
260
262
  - lib/convert_thirty_fps.rb
261
- - lib/count_down_timer_jruby_swing.rb
262
263
  - lib/edl_parser.rb
263
264
  - lib/eight_three.rb
264
265
  - lib/extract/dumpstream.bat
@@ -292,6 +293,7 @@ files:
292
293
  - roadmap_possibilities
293
294
  - spec/arse.srt
294
295
  - spec/auto_window_finder.spec.rb
296
+ - spec/bad_beginning.srt
295
297
  - spec/blanker.spec.rb
296
298
  - spec/common.rb
297
299
  - spec/convert_image.rb
@@ -313,6 +315,7 @@ files:
313
315
  - spec/test_yaml.yml
314
316
  - spec/tsmuxer.output
315
317
  - spec/vlc_programmer.spec.rb
318
+ - spec/youtube_edl.spec.rb
316
319
  - spec/zoom_player_max_edl.spec.rb
317
320
  - template_bats/README_DISTRO.TXT
318
321
  - template_bats/RUN SENSIBLE CINEMA CLICK HERE WINDOWS.bat
@@ -395,21 +398,14 @@ files:
395
398
  - vendor/movie-content-editor-read-only/subtitle.py
396
399
  - vendor/movie-content-editor-read-only/vlc.py
397
400
  - vendor/movie-content-editor-read-only/vlcwidget.py
398
- - vendor/mplayer_patches/apply.bat
399
- - vendor/mplayer_patches/configure_from_betterlogic
400
- - vendor/mplayer_patches/libdvdnav/2905259c3b45529b3d8dedba572b6e4f67a2d8f4.diff
401
- - vendor/mplayer_patches/libdvdnav/83f1c9256f500285e46f1e44bcc74ffce90159db.diff
402
- - vendor/mplayer_patches/libdvdnav/eb91fb74680d30322461a1b9e425918ad4e2b2df.diff
403
- - vendor/mplayer_patches/libdvdnav/jump_to_time.diff
404
- - vendor/mplayer_patches/libdvdnav/non_strict.diff
405
- - vendor/mplayer_patches/mplayer_edl.diff
401
+ - vendor/mplayer_patches/how_to_doze.bat
406
402
  - vendor/mplayer_patches/port_dir/PortIndex.quick
407
403
  - vendor/mplayer_patches/port_dir/how_to
408
404
  - vendor/mplayer_patches/port_dir/multimedia/mplayer-edl/Portfile
409
405
  - vendor/mplayer_patches/port_dir/multimedia/mplayer-edl/files/configure.x11.patch
410
406
  - vendor/mplayer_patches/port_dir/multimedia/mplayer-edl/files/llvm-gcc-workaround.patch
411
407
  - vendor/mplayer_patches/port_dir/multimedia/rdp-projects/Portfile
412
- - vendor/mplayer_patches/updated_lib_too
408
+ - vendor/mplayer_patches/port_dir_is_for_mac
413
409
  - vendor/profs.png
414
410
  - vendor/readme.txt.setpriority
415
411
  - vendor/subfont.ttf
@@ -436,9 +432,15 @@ files:
436
432
  - zamples/edit_decision_lists/dvds/condor_man_widescreen.txt
437
433
  - zamples/edit_decision_lists/dvds/cool runnings.txt
438
434
  - zamples/edit_decision_lists/dvds/court_jester.txt
435
+ - zamples/edit_decision_lists/dvds/edls_being_edited/father_goose.txt
436
+ - zamples/edit_decision_lists/dvds/edls_being_edited/harry_potter_and_the_goblet_of_fire.txt
439
437
  - zamples/edit_decision_lists/dvds/edls_being_edited/making_marriage_work.txt
440
438
  - zamples/edit_decision_lists/dvds/edls_being_edited/national_treasure.txt
439
+ - zamples/edit_decision_lists/dvds/edls_being_edited/percy_jackson_lightening_thief.txt
440
+ - zamples/edit_decision_lists/dvds/edls_being_edited/percy_jackson_lightening_thief_mute_scary.txt
441
+ - zamples/edit_decision_lists/dvds/edls_being_edited/puss_in_boots.txt
441
442
  - zamples/edit_decision_lists/dvds/edls_being_edited/ratatouille.txt
443
+ - zamples/edit_decision_lists/dvds/edls_being_edited/rio.txt
442
444
  - zamples/edit_decision_lists/dvds/edls_being_edited/test_delete_list_for_experimenting_with.txt
443
445
  - zamples/edit_decision_lists/dvds/edls_being_edited/the_explorers.txt
444
446
  - zamples/edit_decision_lists/dvds/finding_neverland.txt
@@ -517,9 +519,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
517
519
  requirements: []
518
520
 
519
521
  rubyforge_project:
520
- rubygems_version: 1.8.13
522
+ rubygems_version: 1.8.23
521
523
  signing_key:
522
524
  specification_version: 3
523
- summary: an EDL scene-skipper/bleeper that works with DVD's and online players like hulu
525
+ summary: an EDL scene-skipper/bleeper that works with DVD's and files and online players like netflix instant
524
526
  test_files: []
525
527
 
@@ -1,55 +0,0 @@
1
- require 'rubygems'
2
- require 'sane' # require_relative
3
- require_relative 'jruby-swing-helpers/swing_helpers'
4
-
5
- include SwingHelpers
6
-
7
- class MainWindow < JFrame
8
-
9
- def show_blocking_message_dialog(message, title = message.split("\n")[0], style= JOptionPane::INFORMATION_MESSAGE)
10
- # I think I'm already on top...
11
- setVisible(true);
12
- toFront()
13
- JOptionPane.showMessageDialog(nil, message, title, style)
14
- true
15
- end
16
-
17
- def initialize
18
- super "countdown"
19
- set_size 150,100
20
- setDefaultCloseOperation JFrame::EXIT_ON_CLOSE # happiness
21
- @jlabel = JLabel.new 'Welcome to Sensible Cinema!'
22
- happy = Font.new("Tahoma", Font::PLAIN, 11)
23
- @jlabel.setFont(happy)
24
- @jlabel.set_bounds(44,44,160,14)
25
- panel = JPanel.new
26
- @panel = panel
27
- @buttons = []
28
- panel.set_layout nil
29
- add panel # why can't I just slap these down?
30
- panel.add @jlabel
31
- @start_time = Time.now
32
- @jlabel.set_text 'welcome...'
33
-
34
- starting_seconds_requested = (ARGV[0] || '25').to_f*60
35
- @switch_image_timer = javax.swing.Timer.new(1000, nil) # nil means it has no default person to call when the action has occurred...
36
- @switch_image_timer.add_action_listener do |e|
37
- seconds_left = starting_seconds_requested - (Time.now - @start_time)
38
- if seconds_left < 0
39
- setVisible(true)
40
- toFront()
41
- show_blocking_message_dialog "timer done!"
42
- @start_time = Time.now
43
- else
44
- # avoid weird re-draw issues
45
- @jlabel.set_text "%02d:%02d" % [seconds_left/60, seconds_left % 60]
46
- end
47
- end
48
- @switch_image_timer.start
49
- self.always_on_top=true
50
- end
51
-
52
- end
53
-
54
- MainWindow.new.show
55
-
@@ -1,12 +0,0 @@
1
- rem assumes you in mplayer/ dir
2
- rem known to work with r 34396, ffmpeg eb4fc6acfede7ced5737c5bf023f
3
- patch -p0 < %~dp0/mplayer_edl.diff
4
- cd libdvdnav
5
- echo 'just retype last part of name'
6
- patch -p0 < %~dp0/libdvdnav/2905259c3b45529b3d8dedba572b6e4f67a2d8f4.diff
7
- patch -p0 < %~dp0/libdvdnav/83f1c9256f500285e46f1e44bcc74ffce90159db.diff
8
- patch -p0 < %~dp0/libdvdnav/eb91fb74680d30322461a1b9e425918ad4e2b2df.diff
9
- @rem below actually work
10
- patch -p0 < %~dp0/libdvdnav/non_strict.diff
11
- patch -p1 < %~dp0/libdvdnav/jump_to_time.diff
12
- cd ..
@@ -1,19 +0,0 @@
1
- diff --git a/src/dvdnav_internal.h b/src/dvdnav_internal.h
2
- index e78470d..089ab14 100644
3
- --- a/src/dvdnav_internal.h
4
- +++ b/src/dvdnav_internal.h
5
- @@ -76,6 +76,14 @@ static inline int _private_gettimeofday( struct timeval *tv, void *tz )
6
- #define DVD_VIDEO_LB_LEN 2048
7
- #endif
8
-
9
- +typedef enum {
10
- + DSI_ILVU_PRE = 1 << 15, /* set during the last 3 VOBU preceeding an interleaved block. */
11
- + DSI_ILVU_BLOCK = 1 << 14, /* set for all VOBU in an interleaved block */
12
- + DSI_ILVU_FIRST = 1 << 13, /* set for the first VOBU for a given angle or scene within a ILVU, or the first VOBU in the preparation (PREU) sequence */
13
- + DSI_ILVU_LAST = 1 << 12, /* set for the last VOBU for a given angle or scene within a ILVU, or the last VOBU in the preparation (PREU) sequence */
14
- + DSI_ILVU_MASK = 0xf000
15
- +} DSI_ILVU;
16
- +
17
- typedef struct read_cache_s read_cache_t;
18
-
19
- /*
@@ -1,16 +0,0 @@
1
- diff --git a/src/dvdnav.c b/src/dvdnav.c
2
- index e82df12..40d44c7 100644
3
- --- a/src/dvdnav.c
4
- +++ b/src/dvdnav.c
5
- @@ -336,8 +336,9 @@ static int32_t dvdnav_get_vobu(dvdnav_t *this, dsi_t *nav_dsi, pci_t *nav_pci, d
6
- dvdnav_angle_change(this, 1);
7
- }
8
- #endif
9
- -
10
- - if(num_angle != 0) {
11
- + /* only use ILVU information if we are at the last vobunit in ILVU */
12
- + /* otherwise we will miss nav packets from vobunits inbetween */
13
- + if(num_angle != 0 && (nav_dsi->sml_pbi.category & DSI_ILVU_MASK) == (DSI_ILVU_BLOCK | DSI_ILVU_LAST)) {
14
-
15
- if((next = nav_pci->nsml_agli.nsml_agl_dsta[angle-1]) != 0) {
16
- if((next & 0x3fffffff) != 0) {
@@ -1,21 +0,0 @@
1
- diff --git a/src/dvdnav.c b/src/dvdnav.c
2
- index 4d0b4f1..c849b18 100644
3
- --- a/src/dvdnav.c
4
- +++ b/src/dvdnav.c
5
- @@ -733,7 +733,7 @@ dvdnav_status_t dvdnav_get_next_cache_block(dvdnav_t *this, uint8_t **buf,
6
- * otherwise it might show stills or menus too shortly */
7
- if ((this->position_current.still || this->pci.hli.hl_gi.hli_ss) && !this->sync_wait_skip) {
8
- this->sync_wait = 1;
9
- - } else {
10
- + }
11
- if( this->position_current.still == 0 || this->skip_still ) {
12
- /* no active cell still -> get us to the next cell */
13
- vm_get_next_cell(this->vm);
14
- @@ -741,7 +741,6 @@ dvdnav_status_t dvdnav_get_next_cache_block(dvdnav_t *this, uint8_t **buf,
15
- this->skip_still = 0;
16
- this->sync_wait_skip = 0;
17
- }
18
- - }
19
- /* handle related state changes in next iteration */
20
- (*event) = DVDNAV_NOP;
21
- (*len) = 0;
@@ -1,654 +0,0 @@
1
- Index: src/searching.c
2
- ===================================================================
3
- --- src/searching.c (revision 1243)
4
- +++ src/searching.c (working copy)
5
- @@ -36,6 +36,7 @@
6
- #include "vm/decoder.h"
7
- #include "vm/vm.h"
8
- #include "dvdnav_internal.h"
9
- +#include <dvdread/ifo_read.h>
10
-
11
- /*
12
- #define LOG_DEBUG
13
- @@ -654,3 +655,575 @@
14
- free(tmp);
15
- return retval;
16
- }
17
- +
18
- +/* Get an admap and admap_len */
19
- +static vobu_admap_t* dvdnav_admap_get(dvdnav_t *this, dvd_state_t *state,
20
- + int32_t *admap_len) {
21
- + vobu_admap_t *admap = NULL;
22
- + switch(state->domain) {
23
- + case FP_DOMAIN:
24
- + case VMGM_DOMAIN:
25
- + admap = this->vm->vmgi->menu_vobu_admap;
26
- + break;
27
- + case VTSM_DOMAIN:
28
- + admap = this->vm->vtsi->menu_vobu_admap;
29
- + break;
30
- + case VTS_DOMAIN:
31
- + admap = this->vm->vtsi->vts_vobu_admap;
32
- + break;
33
- + default: {
34
- + fprintf(MSG_OUT, "Unknown domain");
35
- + return NULL;
36
- + }
37
- + }
38
- + if (admap == NULL) return NULL;
39
- +
40
- + *admap_len = (admap->last_byte + 1 - VOBU_ADMAP_SIZE) / VOBU_ADMAP_SIZE;
41
- + if (*admap_len <= 0) {
42
- + fprintf(MSG_OUT, "admap_len <= 0");
43
- + return NULL;
44
- + }
45
- + return admap;
46
- +}
47
- +
48
- +/* Get a tmap, tmap_len and tmap_interval */
49
- +static vts_tmap_t* dvdnav_tmap_get(dvdnav_t *this, dvd_state_t *state,
50
- + int32_t *tmap_len, int32_t *tmap_interval) {
51
- + int32_t vts_idx = 0;
52
- + domain_t domain;
53
- + ifo_handle_t *ifo = NULL;
54
- + vts_tmapt_t *tmapt = NULL;
55
- + uint16_t tmap_count = 0;
56
- + int32_t pgcN = 0;
57
- + vts_tmap_t *tmap = NULL;
58
- + int32_t result = 0;
59
- +
60
- + vts_idx = state->vtsN;
61
- + domain = state->domain;
62
- + switch(domain) {
63
- + case FP_DOMAIN:
64
- + case VTSM_DOMAIN:
65
- + case VMGM_DOMAIN: {
66
- + ifo = this->vm->vmgi;
67
- + break;
68
- + }
69
- + case VTS_DOMAIN: {
70
- + ifo = this->vm->vtsi;
71
- + break;
72
- + }
73
- + default: {
74
- + fprintf(MSG_OUT, "unknown domain for tmap");
75
- + return NULL;
76
- + }
77
- + }
78
- + if (ifo == NULL) return NULL;
79
- + tmapt = ifo->vts_tmapt;
80
- + /* HACK: ifo->vts_tmapt is NULL b/c ifo_read.c never loads it
81
- + * load ifo->vts_tmapt directly*/
82
- + if (tmapt == NULL) {
83
- + result = ifoRead_VTS_TMAPT(ifo);
84
- + if (!result) {
85
- + return NULL;
86
- + }
87
- + tmapt = ifo->vts_tmapt;
88
- + if (tmapt == NULL) return NULL;
89
- + }
90
- +
91
- + tmap_count = tmapt->nr_of_tmaps;
92
- + pgcN = state->pgcN - 1; /* -1 b/c pgcN is base1 */
93
- + if (pgcN < 0) {
94
- + fprintf(MSG_OUT, "pgcN < 0");
95
- + return NULL;
96
- + }
97
- +
98
- + /* get tmap */
99
- + switch(domain) {
100
- + case FP_DOMAIN:
101
- + case VMGM_DOMAIN:
102
- + case VTSM_DOMAIN: {
103
- + if (tmap_count == 0) {
104
- + fprintf(MSG_OUT, "tmap_count == 0");
105
- + return NULL;
106
- + }
107
- + tmap = &tmapt->tmap[0]; /* ASSUME: vmgi only has one time map */
108
- + break;
109
- + }
110
- + case VTS_DOMAIN: {
111
- + if (pgcN >= tmap_count) {
112
- + fprintf(MSG_OUT, "pgcN >= tmap_count; pgcN=%i tmap_count=%i",
113
- + pgcN, tmap_count);
114
- + return NULL;
115
- + }
116
- + tmap = &tmapt->tmap[pgcN];
117
- + break;
118
- + }
119
- + }
120
- + if (tmap == NULL) return NULL;
121
- +
122
- + /* tmap->tmu is in seconds; convert to millisecs */
123
- + *tmap_interval = tmap->tmu * 1000;
124
- + if (*tmap_interval == 0) {
125
- + fprintf(MSG_OUT, "tmap_interval == 0");
126
- + return NULL;
127
- + }
128
- + *tmap_len = tmap->nr_of_entries;
129
- + if (*tmap_len == 0) {
130
- + fprintf(MSG_OUT, "tmap_len == 0");
131
- + return NULL;
132
- + }
133
- + return tmap;
134
- +}
135
- +
136
- +/* Get a sector from a tmap */
137
- +static int32_t dvdnav_tmap_get_entry(vts_tmap_t *tmap, uint16_t tmap_len,
138
- + int32_t idx, uint32_t *sector) {
139
- + /* tmaps start at idx 0 which represents a sector at time 1 * tmap_interval
140
- + * this creates a "fake" tmap index at idx -1 for sector 0 */
141
- + if (idx == TMAP_IDX_EDGE_BGN) {
142
- + *sector = 0;
143
- + return 1;
144
- + }
145
- + if (idx < TMAP_IDX_EDGE_BGN || idx >= tmap_len) {
146
- + fprintf(MSG_OUT, "idx out of bounds idx=%i %i", idx, tmap_len);
147
- + return 0;
148
- + }
149
- + /* 0x7fffffff unsets discontinuity bit if present */
150
- + *sector = tmap->map_ent[idx] & 0x7fffffff;
151
- + return 1;
152
- +}
153
- +
154
- +/* Do a binary search for earlier admap index near find_sector */
155
- +static int32_t dvdnav_admap_search(vobu_admap_t *admap, uint32_t admap_len,
156
- + uint32_t find_sector, uint32_t *vobu) {
157
- + int32_t adj = 1;
158
- + int32_t prv_pos = 0;
159
- + int32_t prv_len = admap_len;
160
- + int32_t cur_len = 0;
161
- + int32_t cur_idx = 0;
162
- + uint32_t cur_sector = 0;
163
- + while (1) {
164
- + cur_len = prv_len / 2;
165
- + /* need to add 1 when prv_len == 3 (cur_len shoud go to 2, not 1) */
166
- + if (prv_len % 2 == 1) ++cur_len;
167
- + cur_idx = prv_pos + (cur_len * adj);
168
- + if (cur_idx < 0) cur_idx = 0;
169
- + else if (cur_idx >= admap_len) cur_idx = admap_len - 1;
170
- +
171
- + cur_sector = admap->vobu_start_sectors[cur_idx];
172
- + if (find_sector < cur_sector) adj = -1;
173
- + else if (find_sector > cur_sector) adj = 1;
174
- + else if (find_sector == cur_sector) {
175
- + *vobu = cur_idx;
176
- + return 1;
177
- + }
178
- + if (cur_len == 1) {/* no smaller intervals left */
179
- + if (adj == -1) {/* last comparison was greater; take lesser */
180
- + cur_idx -= 1;
181
- + cur_sector = admap->vobu_start_sectors[cur_idx];
182
- + }
183
- + *vobu = cur_idx;
184
- + return 1;
185
- + }
186
- + prv_len = cur_len;
187
- + prv_pos = cur_idx;
188
- + }
189
- +}
190
- +
191
- +/* Do a binary search for the earlier tmap entry near find_sector */
192
- +static int32_t dvdnav_tmap_search(vts_tmap_t *tmap, uint32_t tmap_len,
193
- + uint32_t find_sector, int32_t *tmap_idx, uint32_t *sector) {
194
- + int32_t adj = 1;
195
- + int32_t prv_pos = 0;
196
- + int32_t prv_len = tmap_len;
197
- + int32_t result = 0;
198
- + int32_t cur_len = 0;
199
- + int32_t cur_idx = 0;
200
- + uint32_t cur_sector = 0;
201
- + while (1) {
202
- + cur_len = prv_len / 2;
203
- + /* need to add 1 when prv_len == 3 (cur_len shoud go to 2, not 1) */
204
- + if (prv_len % 2 == 1) ++cur_len;
205
- + cur_idx = prv_pos + (cur_len * adj);
206
- + if (cur_idx < 0) cur_idx = 0;
207
- + else if (cur_idx >= tmap_len) cur_idx = tmap_len - 1;
208
- + cur_sector = 0;
209
- + result = dvdnav_tmap_get_entry(tmap, tmap_len, cur_idx, &cur_sector);
210
- + if (!result) return 0;
211
- + if (find_sector < cur_sector) adj = -1;
212
- + else if (find_sector > cur_sector) adj = 1;
213
- + else if (find_sector == cur_sector) {
214
- + *tmap_idx = cur_idx;
215
- + *sector = cur_sector;
216
- + return 1;
217
- + }
218
- + if (cur_len == 1) {/* no smaller intervals left */
219
- + if (adj == -1) {/* last comparison was greater; take lesser */
220
- + if (cur_idx == 0) { /* fake tmap index for sector 0 */
221
- + cur_idx = TMAP_IDX_EDGE_BGN;
222
- + cur_sector = 0;
223
- + }
224
- + else {
225
- + cur_idx -= 1;
226
- + result = dvdnav_tmap_get_entry(tmap, tmap_len, cur_idx, &cur_sector);
227
- + if (!result) return 0;
228
- + }
229
- + }
230
- + *tmap_idx = cur_idx;
231
- + *sector = cur_sector;
232
- + return 1;
233
- + }
234
- + prv_len = cur_len;
235
- + prv_pos = cur_idx;
236
- + }
237
- +}
238
- +
239
- +/* Find the cell for a given sector */
240
- +static int32_t dvdnav_cell_find(dvdnav_t *this, dvd_state_t *state,
241
- + uint64_t find_val, dvdnav_cell_data_t *cell_data) {
242
- + uint32_t cells_len = 0;
243
- + uint32_t cells_bgn = 0;
244
- + uint32_t cells_end = 0;
245
- + uint32_t cell_idx = 0;
246
- + pgc_t *pgc = NULL;
247
- + int pgN = 0;
248
- + cell_playback_t *cell = NULL;
249
- + int found = 0;
250
- +
251
- + pgc = state->pgc;
252
- + if (pgc == NULL) return 0;
253
- + cells_len = pgc->nr_of_cells;
254
- + if (cells_len == 0) {
255
- + fprintf(MSG_OUT, "cells_len == 0");
256
- + return 0;
257
- + }
258
- +
259
- + /* get cells_bgn, cells_end */
260
- + if (this->pgc_based) {
261
- + cells_bgn = 1;
262
- + cells_end = cells_len;
263
- + }
264
- + else {
265
- + pgN = state->pgN;
266
- + cells_bgn = pgc->program_map[pgN - 1]; /* -1 b/c pgN is 1 based? */
267
- + if (pgN < pgc->nr_of_programs) {
268
- + cells_end = pgc->program_map[pgN] - 1;
269
- + }
270
- + else {
271
- + cells_end = cells_len;
272
- + }
273
- + }
274
- +
275
- + /* search cells */
276
- + for (cell_idx = cells_bgn; cell_idx <= cells_end; cell_idx++) {
277
- + cell = &(pgc->cell_playback[cell_idx - 1]); /* -1 b/c cell is base1 */
278
- + /* if angle block, only consider first angleBlock
279
- + * (others are "redundant" for purpose of search) */
280
- + if ( cell->block_type == BLOCK_TYPE_ANGLE_BLOCK
281
- + && cell->block_mode != BLOCK_MODE_FIRST_CELL) {
282
- + continue;
283
- + }
284
- + cell_data->bgn->sector = cell->first_sector;
285
- + cell_data->end->sector = cell->last_sector;
286
- +
287
- + /* 90 pts to ms */
288
- + cell_data->end->time += (dvdnav_convert_time(&cell->playback_time) / 90);
289
- + if ( find_val >= cell_data->bgn->time
290
- + && find_val <= cell_data->end->time) {
291
- + found = 1;
292
- + break;
293
- + }
294
- + cell_data->bgn->time = cell_data->end->time;
295
- + }
296
- +
297
- + /* found cell: set var */
298
- + if (found) {
299
- + cell_data->idx = cell_idx;
300
- + }
301
- + else
302
- + fprintf(MSG_OUT, "cell not found; find=%"PRId64"", find_val);
303
- + return found;
304
- +}
305
- +
306
- +/* Given two sectors and a fraction, calc the corresponding vobu */
307
- +static int32_t dvdnav_admap_interpolate_vobu(dvdnav_jump_args_t *args,
308
- + dvdnav_pos_data_t *bgn, dvdnav_pos_data_t *end, uint32_t fraction,
309
- + uint32_t *jump_sector) {
310
- + int32_t result = 0;
311
- + uint32_t vobu_len = 0;
312
- + uint32_t vobu_adj = 0;
313
- + uint32_t vobu_idx = 0;
314
- +
315
- + /* get bgn->vobu_idx */
316
- + result = dvdnav_admap_search(args->admap, args->admap_len,
317
- + bgn->sector, &bgn->vobu_idx);
318
- + if (!result) {
319
- + fprintf(MSG_OUT, "admap_interpolate: could not find sector_bgn");
320
- + return 0;
321
- + }
322
- +
323
- + /* get end->vobu_idx */
324
- + result = dvdnav_admap_search(args->admap, args->admap_len,
325
- + end->sector, &end->vobu_idx);
326
- + if (!result) {
327
- + fprintf(MSG_OUT, "admap_interpolate: could not find sector_end");
328
- + return 0;
329
- + }
330
- +
331
- + vobu_len = end->vobu_idx - bgn->vobu_idx;
332
- + /* +500 to round up else 74% of a 4 sec interval = 2 sec */
333
- + vobu_adj = ((fraction * vobu_len) + 500) / 1000;
334
- + /* HACK: need to add +1, or else will land too soon (not sure why) */
335
- + vobu_adj++;
336
- + vobu_idx = bgn->vobu_idx + vobu_adj;
337
- + if (vobu_idx >= args->admap_len) {
338
- + fprintf(MSG_OUT, "admap_interpolate: vobu_idx >= admap_len");
339
- + return 0;
340
- + }
341
- + *jump_sector = args->admap->vobu_start_sectors[vobu_idx];
342
- + return 1;
343
- +}
344
- +
345
- +/* Given two tmap entries and a time, calc the time for the lo tmap entry */
346
- +static int32_t dvdnav_tmap_calc_time_for_tmap_entry(dvdnav_jump_args_t *args,
347
- + dvdnav_pos_data_t *lo, dvdnav_pos_data_t *hi,
348
- + dvdnav_pos_data_t *pos, uint64_t *out_time) {
349
- + int32_t result = 0;
350
- + uint32_t vobu_pct = 0;
351
- + uint64_t time_adj = 0;
352
- +
353
- + if (lo->sector == hi->sector) {
354
- + fprintf(MSG_OUT, "lo->sector == hi->sector: %i", lo->sector);
355
- + return 0;
356
- + }
357
- +
358
- + /* get vobus corresponding to lo, hi, pos */
359
- + result = dvdnav_admap_search(args->admap, args->admap_len,
360
- + lo->sector, &lo->vobu_idx);
361
- + if (!result) {
362
- + fprintf(MSG_OUT, "lo->vobu: lo->sector=%i", lo->sector);
363
- + return 0;
364
- + }
365
- + result = dvdnav_admap_search(args->admap, args->admap_len,
366
- + hi->sector, &hi->vobu_idx);
367
- + if (!result) {
368
- + fprintf(MSG_OUT, "hi->vobu: hi->sector=%i", hi->sector);
369
- + return 0;
370
- + }
371
- + result = dvdnav_admap_search(args->admap, args->admap_len,
372
- + pos->sector, &pos->vobu_idx);
373
- + if (!result) {
374
- + fprintf(MSG_OUT, "pos->vobu: pos->sector=%i", pos->sector);
375
- + return 0;
376
- + }
377
- +
378
- + /* calc position of cell relative to lo */
379
- + vobu_pct = ((pos->vobu_idx - lo->vobu_idx) * 1000)
380
- + / ( hi->vobu_idx - lo->vobu_idx);
381
- + if (vobu_pct < 0 || vobu_pct > 1000) {
382
- + fprintf(MSG_OUT, "vobu_pct must be between 0 and 1000");
383
- + return 0;
384
- + }
385
- +
386
- + /* calc time of lo */
387
- + time_adj = (uint64_t)((args->tmap_interval * vobu_pct) / 1000);
388
- + *out_time = pos->time - time_adj;
389
- + return 1;
390
- +}
391
- +
392
- +/* Find the tmap entries on either side of a given sector */
393
- +static int32_t dvdnav_tmap_get_entries_for_sector(dvdnav_t *this,
394
- + dvd_state_t *state, dvdnav_jump_args_t *args,
395
- + dvdnav_cell_data_t *cell_data, uint32_t find_sector,
396
- + dvdnav_pos_data_t *lo, dvdnav_pos_data_t *hi) {
397
- + int32_t result = 0;
398
- +
399
- + result = dvdnav_tmap_search(args->tmap, args->tmap_len, find_sector,
400
- + &lo->tmap_idx, &lo->sector);
401
- + if (!result) {
402
- + fprintf(MSG_OUT, "could not find lo idx: %i", find_sector);
403
- + return 0;
404
- + }
405
- +
406
- + /* HACK: Most DVDs have a tmap that starts at sector 0
407
- + * However, some have initial dummy cells that are not seekable
408
- + * (restricted = y).
409
- + * These cells will throw off the tmap calcs when in the first playable cell.
410
- + * For now, assume that lo->sector is equal to the cell->bgn->sector
411
- + * Note that for most DVDs this will be 0
412
- + * (Since they will have no dummy cells and cell 1 will start at sector 0)
413
- + */
414
- + if (lo->tmap_idx == TMAP_IDX_EDGE_BGN) {
415
- + lo->sector = cell_data->bgn->sector;
416
- + }
417
- +
418
- + if (lo->tmap_idx == args->tmap_len - 1) {
419
- + /* lo is last tmap entry; "fake" entry for one beyond
420
- + * and mark it with cell_end_sector */
421
- + hi->tmap_idx = TMAP_IDX_EDGE_END;
422
- + hi->sector = cell_data->end->sector;
423
- + }
424
- + else {
425
- + hi->tmap_idx = lo->tmap_idx + 1;
426
- + result = dvdnav_tmap_get_entry(args->tmap, args->tmap_len,
427
- + hi->tmap_idx, &hi->sector);
428
- + if (!result) {
429
- + fprintf(MSG_OUT, "could not find hi idx: %i", find_sector);
430
- + return 0;
431
- + }
432
- + }
433
- + return 1;
434
- +}
435
- +
436
- +/* Find the nearest vobu by using the tmap */
437
- +static int32_t dvdnav_find_vobu_by_tmap(dvdnav_t *this, dvd_state_t *state,
438
- + dvdnav_jump_args_t *args, dvdnav_cell_data_t *cell_data,
439
- + dvdnav_pos_data_t *jump) {
440
- + uint64_t seek_offset = 0;
441
- + uint32_t seek_idx = 0;
442
- + int32_t result = 0;
443
- + dvdnav_pos_data_t *cell_bgn_lo = NULL;
444
- + dvdnav_pos_data_t *cell_bgn_hi = NULL;
445
- + dvdnav_pos_data_t *jump_lo = NULL;
446
- + dvdnav_pos_data_t *jump_hi = NULL;
447
- +
448
- + /* get tmap, tmap_len, tmap_interval */
449
- + args->tmap = dvdnav_tmap_get(this, state,
450
- + &args->tmap_len, &args->tmap_interval);
451
- + if (args->tmap == NULL) return 0;
452
- +
453
- + /* get tmap entries on either side of cell_bgn */
454
- + cell_bgn_lo = &(dvdnav_pos_data_t){0};
455
- + cell_bgn_hi = &(dvdnav_pos_data_t){0};
456
- + result = dvdnav_tmap_get_entries_for_sector(this, state, args, cell_data,
457
- + cell_data->bgn->sector, cell_bgn_lo, cell_bgn_hi);
458
- + if (!result) return 0;
459
- +
460
- + /* calc time of cell_bgn_lo */
461
- + result = dvdnav_tmap_calc_time_for_tmap_entry(args, cell_bgn_lo, cell_bgn_hi,
462
- + cell_data->bgn, &cell_bgn_lo->time);
463
- + if (!result) return 0;
464
- +
465
- + /* calc time of jump_time relative to cell_bgn_lo */
466
- + seek_offset = jump->time - cell_bgn_lo->time;
467
- + seek_idx = (uint32_t)(seek_offset / args->tmap_interval);
468
- + uint32_t seek_remainder = seek_offset - (seek_idx * args->tmap_interval);
469
- + uint32_t seek_pct = (seek_remainder * 1000) / args->tmap_interval;
470
- +
471
- + /* get tmap entries on either side of jump_time */
472
- + jump_lo = &(dvdnav_pos_data_t){0};
473
- + jump_hi = &(dvdnav_pos_data_t){0};
474
- +
475
- + /* if seek_idx == 0, then tmap_indexes are the same, do not re-get
476
- + * also, note cell_bgn_lo will already have sector if TMAP_IDX_EDGE_BGN */
477
- + if (seek_idx == 0) {
478
- + jump_lo = cell_bgn_lo;
479
- + jump_hi = cell_bgn_hi;
480
- + }
481
- + else {
482
- + jump_lo->tmap_idx = (uint32_t)(cell_bgn_lo->tmap_idx + seek_idx);
483
- + result = dvdnav_tmap_get_entry(args->tmap, args->tmap_len,
484
- + jump_lo->tmap_idx, &jump_lo->sector);
485
- + if (!result) return 0;
486
- +
487
- + /* +1 handled by dvdnav_tmap_get_entry */
488
- + jump_hi->tmap_idx = jump_lo->tmap_idx + 1;
489
- + result = dvdnav_tmap_get_entry(args->tmap, args->tmap_len,
490
- + jump_hi->tmap_idx, &jump_hi->sector);
491
- + if (!result) return 0;
492
- + }
493
- +
494
- + /* interpolate sector */
495
- + result = dvdnav_admap_interpolate_vobu(args, jump_lo, jump_hi,
496
- + seek_pct, &jump->sector);
497
- +
498
- + return result;
499
- +}
500
- +
501
- +/* Find the nearest vobu by using the cell boundaries */
502
- +static int32_t dvdnav_find_vobu_by_cell_boundaries(dvdnav_t *this,
503
- + dvdnav_jump_args_t *args, dvdnav_cell_data_t *cell_data,
504
- + dvdnav_pos_data_t *jump) {
505
- + uint64_t jump_offset = 0;
506
- + uint64_t cell_len = 0;
507
- + uint32_t jump_pct = 0;
508
- + int32_t result = 0;
509
- +
510
- + /* get jump_offset */
511
- + jump_offset = jump->time - cell_data->bgn->time;
512
- + if (jump_offset < 0) {
513
- + fprintf(MSG_OUT, "jump_offset < 0");
514
- + return 0;
515
- + }
516
- + cell_len = cell_data->end->time - cell_data->bgn->time;
517
- + if (cell_len < 0) {
518
- + fprintf(MSG_OUT, "cell_len < 0");
519
- + return 0;
520
- + }
521
- + jump_pct = (jump_offset * 1000) / cell_len;
522
- +
523
- + /* get sector */
524
- + /* NOTE: end cell sector in VTS_PGC is last sector of cell
525
- + * this last sector is not the start of a VOBU
526
- + * +1 to get sector that is the start of a VOBU
527
- + * start of a VOBU is needed in order to index into admap */
528
- + cell_data->end->sector += 1;
529
- + result = dvdnav_admap_interpolate_vobu(args,
530
- + cell_data->bgn, cell_data->end, jump_pct, &jump->sector);
531
- + if (!result) {
532
- + fprintf(MSG_OUT, "find_by_admap.interpolate");
533
- + return 0;
534
- + }
535
- + return 1;
536
- +}
537
- +
538
- +dvdnav_status_t dvdnav_jump_to_sector_by_time(dvdnav_t *this,
539
- + uint64_t time_in_pts_ticks) {
540
- + int32_t result = 1;
541
- + dvd_state_t *state = NULL;
542
- + uint32_t sector_off = 0;
543
- + dvdnav_pos_data_t *jump = NULL;
544
- + dvdnav_cell_data_t *cell_data = NULL;
545
- + dvdnav_jump_args_t *args = NULL;
546
- +
547
- + jump = &(dvdnav_pos_data_t){0};
548
- + /* convert time to milliseconds */
549
- + jump->time = time_in_pts_ticks / 90;
550
- +
551
- + /* get variables that will be used across both functions */
552
- + state = &(this->vm->state);
553
- + if (state == NULL) goto exit;
554
- +
555
- + /* get cell info */
556
- + cell_data = &(dvdnav_cell_data_t){0};
557
- + cell_data->bgn = &(dvdnav_pos_data_t){0};
558
- + cell_data->end = &(dvdnav_pos_data_t){0};
559
- + result = dvdnav_cell_find(this, state, jump->time, cell_data);
560
- + if (!result) goto exit;
561
- +
562
- + /* get admap */
563
- + args = &(dvdnav_jump_args_t){0};
564
- + args->admap = dvdnav_admap_get(this, state, &args->admap_len);
565
- + if (args->admap == NULL) goto exit;
566
- +
567
- + /* find sector */
568
- + result = dvdnav_find_vobu_by_tmap(this, state, args, cell_data, jump);
569
- + if (!result) {// bad tmap; interpolate over cell
570
- + result = dvdnav_find_vobu_by_cell_boundaries(this, args, cell_data, jump);
571
- + if (!result) {
572
- + goto exit;
573
- + }
574
- + }
575
- +
576
- + /* jump to sector */
577
- + sector_off = jump->sector - cell_data->bgn->sector;
578
- + this->cur_cell_time = 0;
579
- + if (vm_jump_cell_block(this->vm, cell_data->idx, sector_off)) {
580
- + pthread_mutex_lock(&this->vm_lock);
581
- + this->vm->hop_channel += HOP_SEEK;
582
- + pthread_mutex_unlock(&this->vm_lock);
583
- + result = 1;
584
- + }
585
- +
586
- +exit:
587
- + return result;
588
- +}
589
- Index: src/dvdnav_internal.h
590
- ===================================================================
591
- --- src/dvdnav_internal.h (revision 1243)
592
- +++ src/dvdnav_internal.h (working copy)
593
- @@ -125,6 +125,42 @@
594
- } ATTRIBUTE_PACKED spu_status_t;
595
- #endif
596
-
597
- +/*
598
- + * Describes a given time, and the closest sector, vobu and tmap index
599
- + */
600
- +typedef struct {
601
- + uint64_t time;
602
- + uint32_t sector;
603
- + uint32_t vobu_idx;
604
- + int32_t tmap_idx;
605
- +} dvdnav_pos_data_t;
606
- +
607
- +/*
608
- + * Encapsulates cell data
609
- + */
610
- +typedef struct {
611
- + int32_t idx;
612
- + dvdnav_pos_data_t *bgn;
613
- + dvdnav_pos_data_t *end;
614
- +} dvdnav_cell_data_t;
615
- +
616
- +/*
617
- + * Encapsulates common variables used by internal functions of jump_to_time
618
- + */
619
- +typedef struct {
620
- + vobu_admap_t *admap;
621
- + int32_t admap_len;
622
- + vts_tmap_t *tmap;
623
- + int32_t tmap_len;
624
- + int32_t tmap_interval;
625
- +} dvdnav_jump_args_t;
626
- +
627
- +/*
628
- + * Utility constants for jump_to_time
629
- + */
630
- +#define TMAP_IDX_EDGE_BGN -1
631
- +#define TMAP_IDX_EDGE_END -2
632
- +
633
- typedef struct dvdnav_vobu_s {
634
- int32_t vobu_start; /* Logical Absolute. MAX needed is 0x300000 */
635
- int32_t vobu_length;
636
- Index: src/dvdnav/dvdnav.h
637
- ===================================================================
638
- --- src/dvdnav/dvdnav.h (revision 1243)
639
- +++ src/dvdnav/dvdnav.h (working copy)
640
- @@ -388,6 +388,14 @@
641
- uint64_t time);
642
-
643
- /*
644
- + * Find the nearest vobu and jump to it
645
- + *
646
- + * Alternative to dvdnav_time_search
647
- + */
648
- +dvdnav_status_t dvdnav_jump_to_sector_by_time(dvdnav_t *this,
649
- + uint64_t time_in_pts_ticks);
650
- +
651
- +/*
652
- * Stop playing current position and play the "GoUp"-program chain.
653
- * (which generally leads to the title menu or a higher-level menu).
654
- */