sensible-cinema 0.28.1 → 0.34.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (185) hide show
  1. data/{README → README.TXT} +35 -14
  2. data/Rakefile +49 -41
  3. data/TODO +337 -250
  4. data/VERSION +1 -1
  5. data/bin/sensible-cinema +15 -14
  6. data/bin/sensible-cinema-cli +1 -1
  7. data/business_ideas.txt +8 -0
  8. data/change_log_with_feature_list.txt +198 -1
  9. data/documentation/is_it_legal_to_copy_dvds.txt +44 -30
  10. data/goc.bat +1 -1
  11. data/gpl-2.0.txt +339 -0
  12. data/history_and_related_works_list.txt +37 -33
  13. data/{cone.png → inventionzy_files/cone.png} +0 -0
  14. data/legal_draft +23 -0
  15. data/lib/add_any_bundled_gems_to_load_path.rb +4 -3
  16. data/lib/check_installed_mac.rb +10 -10
  17. data/lib/count_down_timer_jruby_swing.rb +4 -4
  18. data/lib/edl_parser.rb +155 -142
  19. data/lib/extract/dumpstream.bat +1 -0
  20. data/lib/extract/get_init.bat +3 -0
  21. data/lib/extract/pause_early.rb +13 -0
  22. data/lib/gui/base.rb +707 -0
  23. data/lib/gui/create-file.rb +244 -0
  24. data/lib/gui/create.rb +565 -0
  25. data/lib/gui/dependencies.rb +177 -0
  26. data/lib/gui/normal.rb +190 -0
  27. data/lib/gui/{sensible-cinema-upconvert.rb → upconvert.rb} +33 -14
  28. data/lib/keyboard_input.rb +0 -2
  29. data/lib/mencoder_wrapper.rb +8 -3
  30. data/lib/movie_hasher.rb +27 -0
  31. data/lib/mplayer_edl.rb +1 -0
  32. data/lib/subtitle_profanity_finder.rb +141 -103
  33. data/lib/vlc_programmer.rb +1 -1
  34. data/lib/zoom_player_max_edl.rb +50 -0
  35. data/{developer_how_to_contribute_to_the_project.txt → notes_for_potential_developers.txt} +18 -11
  36. data/roadmap_possibilities +12 -0
  37. data/spec/arse.srt +6 -1
  38. data/spec/dragon.srt +3 -0
  39. data/spec/edl_parser.spec.rb +57 -52
  40. data/spec/mencoder_wrapper.spec.rb +26 -19
  41. data/spec/mplayer_edl.spec.rb +40 -10
  42. data/spec/notes +3043 -9
  43. data/spec/sensible_cinema_gui.spec.rb +8 -3
  44. data/spec/subtitle_profanity_finder.spec.rb +91 -36
  45. data/spec/zoom_player_max_edl.spec.rb +29 -0
  46. data/template_bats/README_DISTRO.TXT +3 -1
  47. data/template_bats/RUN SENSIBLE CINEMA CLICK HERE WINDOWS.bat +25 -0
  48. data/template_bats/mac/RUN SENSIBLE CINEMA CLICK HERE.command +2 -1
  49. data/template_bats/mac/advanced--create or edit sensible cinema edit list files.command +2 -1
  50. data/template_bats/mac/advanced--run-upconverting-video-player.command +2 -1
  51. data/template_bats/pc/advanced--create or edit sensible cinema edit list files.bat +2 -0
  52. data/template_bats/pc/advanced--run-upconverting-video-player.bat +2 -0
  53. data/todo.inventionzy.txt +69 -2
  54. data/todo.propaganda +34 -10
  55. data/todo.upconvert +8 -1
  56. data/{upconvert_netflix/latest2 → upconvert_from_screen}/go_upscaling.bat +0 -0
  57. data/{also_see_rogerdpack_youtube_account_and_sourceforge_files_movies_account → upconvert_from_screen/go_upscaling_works} +0 -0
  58. data/{upconvert_netflix → upconvert_from_screen/old}/latest2/combine_video.avs +0 -0
  59. data/{upconvert_netflix → upconvert_from_screen/old}/latest2/go_no_upscaling.bat +0 -0
  60. data/upconvert_from_screen/old/latest2/go_upscaling.bat +12 -0
  61. data/{upconvert_netflix → upconvert_from_screen/old}/latest2/push2.GRF +0 -0
  62. data/upconvert_from_screen/old/latest2/push3.grf +0 -0
  63. data/{upconvert_netflix → upconvert_from_screen/old}/latest2/setup_capture_coords.rb +0 -0
  64. data/{upconvert_netflix → upconvert_from_screen/old}/latest2/setup_directshow_filter_params.rb +0 -0
  65. data/{upconvert_netflix → upconvert_from_screen/old}/latest2/upconvert_from_screen_me2.avs +1 -1
  66. data/{upconvert_netflix → upconvert_from_screen}/old/latest_now_possibly_oudated/push2.GRF +0 -0
  67. data/{upconvert_netflix → upconvert_from_screen}/old/latest_now_possibly_oudated/upconvert_from_screen_me2.avs +0 -0
  68. data/{upconvert_netflix → upconvert_from_screen}/old/position_window.png +0 -0
  69. data/{upconvert_netflix → upconvert_from_screen}/old/push_source_desktop.GRF +0 -0
  70. data/{upconvert_netflix → upconvert_from_screen/old}/record_screen/record.bat +0 -0
  71. data/{upconvert_netflix → upconvert_from_screen}/old/upconvert_from_screen.avs +0 -0
  72. data/{upconvert_netflix → upconvert_from_screen}/old/upconvert_from_screen_me.avs +0 -0
  73. data/{upconvert_netflix → upconvert_from_screen}/old/upconvert_from_screen_me2.avs +0 -0
  74. data/{upconvert_netflix → upconvert_from_screen}/old/upconvert_from_screen_me_push_source.avs +0 -0
  75. data/{upconvert_netflix → upconvert_from_screen}/old/uscreen.GRF +0 -0
  76. data/{upconvert_netflix → upconvert_from_screen}/old/uscreen_me.GRF +0 -0
  77. data/upconvert_from_screen/push3.grf +0 -0
  78. data/upconvert_from_screen/upconvert_from_screen_me2.avs +19 -0
  79. data/vendor/mplayer_patches/apply.bat +12 -0
  80. data/vendor/{rdp-win32screenshot-0.0.9/RDP_BRANCH_HAS_MASTER_WITH_CORRECT_VERSION_NUMBER → mplayer_patches/configure_from_betterlogic} +0 -0
  81. data/vendor/mplayer_patches/libdvdnav/2905259c3b45529b3d8dedba572b6e4f67a2d8f4.diff +19 -0
  82. data/vendor/mplayer_patches/libdvdnav/83f1c9256f500285e46f1e44bcc74ffce90159db.diff +16 -0
  83. data/vendor/mplayer_patches/libdvdnav/eb91fb74680d30322461a1b9e425918ad4e2b2df.diff +21 -0
  84. data/vendor/mplayer_patches/libdvdnav/jump_to_time.diff +654 -0
  85. data/vendor/mplayer_patches/libdvdnav/non_strict.diff +13 -0
  86. data/vendor/mplayer_patches/mplayer_edl.diff +354 -0
  87. data/vendor/mplayer_patches/port_dir/PortIndex.quick +2 -0
  88. data/vendor/mplayer_patches/port_dir/how_to +13 -0
  89. data/vendor/mplayer_patches/port_dir/multimedia/mplayer-edl/Portfile +300 -0
  90. data/vendor/mplayer_patches/port_dir/multimedia/mplayer-edl/files/configure.x11.patch +20 -0
  91. data/vendor/mplayer_patches/port_dir/multimedia/mplayer-edl/files/llvm-gcc-workaround.patch +11 -0
  92. data/vendor/mplayer_patches/port_dir/multimedia/rdp-projects/Portfile +43 -0
  93. data/vendor/{rdp-win32screenshot-0.0.9/RDP_VERSION_IS_IN_RDP_BRANCH → mplayer_patches/updated_lib_too} +0 -0
  94. data/vendor/{readme.txt → readme.txt.setpriority} +0 -0
  95. data/www/content_editor.html +28 -28
  96. data/www/index.html +6 -1
  97. data/www/upconverting_movie_player.html +13 -3
  98. data/www/youtube_edl/.htaccess +44 -0
  99. data/{inventionzy_files/control_youtube.html → www/youtube_edl/control_youtube.rhtml} +39 -33
  100. data/www/youtube_edl/dispatch.fcgi +25 -0
  101. data/www/youtube_edl/render_edited.rb +25 -0
  102. data/{inventionzy_files/serve.rb → www/youtube_edl/server_this_dir.rb} +0 -0
  103. data/www/youtube_edl/todo +23 -0
  104. data/www/zoomplayer_max.png +0 -0
  105. data/zamples/edit_decision_lists/dvds/Harry Potter 2 chamber of secrets.txt +10 -5
  106. data/zamples/edit_decision_lists/dvds/aladdin.txt +30 -0
  107. data/zamples/edit_decision_lists/dvds/bambi.txt +1 -1
  108. data/zamples/edit_decision_lists/dvds/big_buck_bunny_dvd.txt +2 -0
  109. data/zamples/edit_decision_lists/dvds/bobs_big_plan.txt +2 -2
  110. data/zamples/edit_decision_lists/dvds/cars_2.txt +26 -0
  111. data/zamples/edit_decision_lists/dvds/cars_disney.txt +1 -1
  112. data/zamples/edit_decision_lists/dvds/condor_man_widescreen.txt +22 -0
  113. data/zamples/edit_decision_lists/dvds/court_jester.txt +10 -13
  114. data/zamples/edit_decision_lists/dvds/edls_being_edited/making_marriage_work.txt +15 -0
  115. data/zamples/edit_decision_lists/dvds/edls_being_edited/national_treasure.txt +23 -0
  116. data/zamples/edit_decision_lists/dvds/edls_being_edited/ratatouille.txt +35 -0
  117. data/zamples/edit_decision_lists/dvds/edls_being_edited/the_explorers.txt +49 -0
  118. data/zamples/edit_decision_lists/dvds/finding_neverland.txt +32 -0
  119. data/zamples/edit_decision_lists/dvds/flight_of_the_navigator.txt +22 -16
  120. data/zamples/edit_decision_lists/dvds/harry_potter_3_prisoner_of_azkaban.txt +21 -4
  121. data/zamples/edit_decision_lists/dvds/hitchhiker's_guide_to_the_galaxy.txt +1 -1
  122. data/zamples/edit_decision_lists/dvds/{edls_being_edited/king_of_kings.txt → king_of_kings.txt} +5 -5
  123. data/zamples/edit_decision_lists/dvds/nanny_mcphee.txt +31 -0
  124. data/zamples/edit_decision_lists/dvds/pack_jackson_wedding_2007-03-03.txt +9 -2
  125. data/zamples/edit_decision_lists/dvds/remember_the_titans.txt +35 -0
  126. data/zamples/edit_decision_lists/dvds/sintel_open_source_blender_ntsc_dvd.txt +8 -4
  127. data/zamples/edit_decision_lists/dvds/speed_racer.txt +1 -1
  128. data/zamples/edit_decision_lists/dvds/tangled.txt +21 -0
  129. data/zamples/edit_decision_lists/dvds/tron_legacy.txt +4 -1
  130. data/zamples/edit_decision_lists/files/conference_music_video.txt +10 -0
  131. data/zamples/edit_decision_lists/notes_on_movies_without_edls_yet/tron.txt +10 -0
  132. data/zamples/edit_decision_lists/old_not_yet_updated/example_edit_decision_list.txt +1 -1
  133. metadata +139 -117
  134. data/conclusions +0 -6
  135. data/documentation/how_to_create_your_own_delete_lists.txt +0 -69
  136. data/lib/gui/sensible-cinema-base.rb +0 -620
  137. data/lib/gui/sensible-cinema-create.rb +0 -331
  138. data/lib/gui/sensible-cinema-dependencies.rb +0 -28
  139. data/lib/gui/sensible-cinema-normal.rb +0 -351
  140. data/lib/gui/sensible-cinema-side-by-side.rb +0 -27
  141. data/lib/shutdown_kill.rb +0 -32
  142. data/lib/storage.rb +0 -105
  143. data/ocr.todo_if_need_speed +0 -6
  144. data/upconvert_netflix/record_screen/recording/1.png +0 -0
  145. data/upconvert_netflix/record_screen/recording/10.png +0 -0
  146. data/upconvert_netflix/record_screen/recording/2.png +0 -0
  147. data/upconvert_netflix/record_screen/recording/3.png +0 -0
  148. data/upconvert_netflix/record_screen/recording/4.png +0 -0
  149. data/upconvert_netflix/record_screen/recording/5.png +0 -0
  150. data/upconvert_netflix/record_screen/recording/6.png +0 -0
  151. data/upconvert_netflix/record_screen/recording/7.png +0 -0
  152. data/upconvert_netflix/record_screen/recording/8.png +0 -0
  153. data/upconvert_netflix/record_screen/recording/9.png +0 -0
  154. data/upconvert_netflix/record_screen/recording/d.png +0 -0
  155. data/vendor/monkey.png +0 -0
  156. data/vendor/rdp-win32screenshot-0.0.9/.document +0 -5
  157. data/vendor/rdp-win32screenshot-0.0.9/History.rdoc +0 -53
  158. data/vendor/rdp-win32screenshot-0.0.9/LICENSE +0 -20
  159. data/vendor/rdp-win32screenshot-0.0.9/README.rdoc +0 -95
  160. data/vendor/rdp-win32screenshot-0.0.9/Rakefile +0 -63
  161. data/vendor/rdp-win32screenshot-0.0.9/VERSION +0 -1
  162. data/vendor/rdp-win32screenshot-0.0.9/enumerated +0 -55576
  163. data/vendor/rdp-win32screenshot-0.0.9/lib/aero_offscreen_srccopy_captureblt_doesnt_have_everything.bmp.gz +0 -0
  164. data/vendor/rdp-win32screenshot-0.0.9/lib/enumerate.rb +0 -6
  165. data/vendor/rdp-win32screenshot-0.0.9/lib/firefox.bmp +0 -0
  166. data/vendor/rdp-win32screenshot-0.0.9/lib/normal.bmp +0 -0
  167. data/vendor/rdp-win32screenshot-0.0.9/lib/normal2.bmp +0 -0
  168. data/vendor/rdp-win32screenshot-0.0.9/lib/notes +0 -5
  169. data/vendor/rdp-win32screenshot-0.0.9/lib/snapshot.rb +0 -10
  170. data/vendor/rdp-win32screenshot-0.0.9/lib/srccopy.bmp +0 -0
  171. data/vendor/rdp-win32screenshot-0.0.9/lib/srccopyplus.bmp +0 -0
  172. data/vendor/rdp-win32screenshot-0.0.9/lib/srccopyplusdirectx.bmp +0 -0
  173. data/vendor/rdp-win32screenshot-0.0.9/lib/vc.bmp +0 -0
  174. data/vendor/rdp-win32screenshot-0.0.9/lib/win32/screenshot.rb +0 -95
  175. data/vendor/rdp-win32screenshot-0.0.9/lib/win32/screenshot/bitmap_maker.rb +0 -200
  176. data/vendor/rdp-win32screenshot-0.0.9/lib/win32/util.rb +0 -93
  177. data/vendor/rdp-win32screenshot-0.0.9/spec/spec.opts +0 -1
  178. data/vendor/rdp-win32screenshot-0.0.9/spec/spec_helper.rb +0 -85
  179. data/vendor/rdp-win32screenshot-0.0.9/spec/win32_screenshot_spec.rb +0 -194
  180. data/vendor/rdp-win32screenshot-0.0.9/spec/win32_screenshot_util_spec.rb +0 -75
  181. data/vendor/rdp-win32screenshot-0.0.9/win32screenshot.gemspec +0 -69
  182. data/vendor/tsmuxer_1.10.6/licence.txt +0 -42
  183. data/zamples/edit_decision_lists/dvds/making_marriage_work.txt +0 -15
  184. data/zamples/edit_decision_lists/notes/tron.txt +0 -4
  185. data/zamples/edit_decision_lists/old_not_yet_updated/dvds/making marriage work.txt +0 -9
@@ -1,5 +1,10 @@
1
1
  == dvd upconvert ==
2
2
 
3
+ how does powerdvd's upscaling work?
4
+
5
+ purevideo?/zoomplayer
6
+
7
+ what does -ss do in mplayer?
3
8
 
4
9
  ask mplayer "can you use accurate rounding with lanczos? I don't think you can..."
5
10
 
@@ -21,7 +26,7 @@ check out the various posts of people comparing images, try mine out against the
21
26
  === netflix/OS screen capture ===
22
27
 
23
28
  can I make it look awesome?
24
- pushdesktop\TODO high prio
29
+ pushdesktop avoid dupe's?
25
30
 
26
31
  ==== some day ====
27
32
  perfect the looks of absolutely everything upconverted LOL
@@ -36,6 +41,8 @@ check out the various posts of people comparing images, try mine out against the
36
41
 
37
42
  == never ==
38
43
 
44
+ check what zoomplayer suggests for upconversion
45
+
39
46
  test out xvda too...Radeon 4000 for example :P
40
47
  I guess ffmpeg already supports it...
41
48
 
@@ -0,0 +1,12 @@
1
+ mplayer -nocache -geometry 70%x70% -sws 9 -ssf ls=25.0 -ssf cs=7.0 -vf hqdn3d=7:7:7:7,scale=1680:-10:0:0:3 upconvert_from_screen_me2.avs
2
+
3
+ @rem hqdn3d[=luma_spatial:chroma_spatial:luma_tmp:chroma_tmp]
4
+
5
+
6
+
7
+
8
+ @rem 0:1:4:4 for DVD LOL
9
+ @rem pp=hb:y/vb:y,
10
+
11
+
12
+ @rem mplayer autoq=100 -nocache -geometry 50%x40% -sws 9 -ssf ls=75.0 -ssf cs=7.0 -vf nr=1000,scale=1680:-10:0:0:4 upconvert_from_screen_me2.avs
@@ -1,6 +1,6 @@
1
1
  # from http://avisynth.org/mediawiki/Enhancing_dvd_videos
2
2
 
3
- Video = DirectShowSource("push2.GRF", fps=35, audio=False, framecount=1000000) # fps appears to be a "max" fps
3
+ Video = DirectShowSource("push3.GRF", fps=35, audio=False, framecount=1000000) # fps appears to be a "max" fps
4
4
  Return Video
5
5
 
6
6
  #
@@ -0,0 +1,19 @@
1
+ # from http://avisynth.org/mediawiki/Enhancing_dvd_videos
2
+
3
+ Video = DirectShowSource("push3.GRF", fps=35, audio=False, framecount=1000000) # fps appears to be a "max" fps
4
+ Return Video
5
+
6
+ #
7
+ # these are the size of your monitor that the output is displayed on. Unless it lags too much, then try experimenting with smaller values
8
+ # Video = ConvertToYUY2 (Video)
9
+ # screen_width = 1024 # CHANGE THIS TODO propagate it...
10
+ # screen_height = 768 # CHANGE THIS
11
+ #
12
+ # # note that you can get even better looking images by say, upscaling to 2x your current screen resolution, by uncommenting the following two lines
13
+ # screen_width = screen_width*2
14
+ # screen_height = screen_height*2
15
+ #
16
+ # Video = Lanczos4Resize (Video, screen_width, screen_height) # said to be a good upsampler...hmm...
17
+ #
18
+ # Video = Sharpen (Video, 0.78) # Helps sharpen smoothness enlarging does. 0.78 = (1.25*(1024/720))-1
19
+ # Return Video
@@ -0,0 +1,12 @@
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 ..
@@ -0,0 +1,19 @@
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
+ /*
@@ -0,0 +1,16 @@
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) {
@@ -0,0 +1,21 @@
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;
@@ -0,0 +1,654 @@
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
+ */