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.
- data/.gitmodules +1 -1
- data/README.TXT +19 -20
- data/Rakefile +191 -195
- data/TODO +122 -149
- data/VERSION +1 -1
- data/bin/sensible-cinema +52 -52
- data/change_log_with_feature_list.txt +532 -481
- data/documentation/troubleshooting.txt +3 -9
- data/go.bat +2 -2
- data/go.sh +1 -0
- data/goc.bat +1 -1
- data/goc.sh +1 -0
- data/lib/check_installed_mac.rb +2 -10
- data/lib/edl_parser.rb +40 -16
- data/lib/gui/base.rb +85 -27
- data/lib/gui/create-file.rb +3 -2
- data/lib/gui/create.rb +118 -101
- data/lib/gui/dependencies.rb +110 -76
- data/lib/gui/normal.rb +32 -81
- data/lib/mplayer_edl.rb +7 -1
- data/lib/subtitle_profanity_finder.rb +10 -5
- data/notes_for_potential_developers.txt +18 -25
- data/spec/bad_beginning.srt +3778 -0
- data/spec/edl_parser.spec.rb +4 -0
- data/spec/notes +327 -167
- data/spec/youtube_edl.spec.rb +28 -0
- data/template_bats/RUN SENSIBLE CINEMA CLICK HERE WINDOWS.bat +2 -2
- data/todo.inventionzy.txt +3 -1
- data/vendor/mplayer_patches/how_to_doze.bat +6 -0
- data/vendor/mplayer_patches/port_dir/PortIndex.quick +1 -1
- data/vendor/mplayer_patches/port_dir/how_to +16 -9
- data/vendor/mplayer_patches/port_dir/multimedia/mplayer-edl/Portfile +10 -25
- data/vendor/mplayer_patches/port_dir/multimedia/rdp-projects/Portfile +2 -2
- data/vendor/mplayer_patches/{configure_from_betterlogic → port_dir_is_for_mac} +0 -0
- data/www/content_editor.html +9 -5
- data/zamples/edit_decision_lists/dvds/big_buck_bunny_dvd.txt +7 -4
- data/zamples/edit_decision_lists/dvds/court_jester.txt +0 -1
- data/zamples/edit_decision_lists/dvds/edls_being_edited/father_goose.txt +41 -0
- data/zamples/edit_decision_lists/dvds/edls_being_edited/harry_potter_and_the_goblet_of_fire.txt +45 -0
- data/zamples/edit_decision_lists/dvds/edls_being_edited/national_treasure.txt +6 -3
- data/zamples/edit_decision_lists/dvds/edls_being_edited/percy_jackson_lightening_thief.txt +40 -0
- data/zamples/edit_decision_lists/dvds/edls_being_edited/percy_jackson_lightening_thief_mute_scary.txt +23 -0
- data/zamples/edit_decision_lists/dvds/edls_being_edited/puss_in_boots.txt +33 -0
- data/zamples/edit_decision_lists/dvds/edls_being_edited/ratatouille.txt +5 -5
- data/zamples/edit_decision_lists/dvds/edls_being_edited/rio.txt +24 -0
- data/zamples/edit_decision_lists/dvds/sintel_open_source_blender_ntsc_dvd.txt +0 -1
- metadata +17 -15
- data/lib/count_down_timer_jruby_swing.rb +0 -55
- data/vendor/mplayer_patches/apply.bat +0 -12
- data/vendor/mplayer_patches/libdvdnav/2905259c3b45529b3d8dedba572b6e4f67a2d8f4.diff +0 -19
- data/vendor/mplayer_patches/libdvdnav/83f1c9256f500285e46f1e44bcc74ffce90159db.diff +0 -16
- data/vendor/mplayer_patches/libdvdnav/eb91fb74680d30322461a1b9e425918ad4e2b2df.diff +0 -21
- data/vendor/mplayer_patches/libdvdnav/jump_to_time.diff +0 -654
- data/vendor/mplayer_patches/libdvdnav/non_strict.diff +0 -13
- data/vendor/mplayer_patches/mplayer_edl.diff +0 -354
- 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 [
|
10
|
-
"0:22:42.52" , "0:22:44.42", "profanity", "deity", "Five minutes, chef. - Oh, [
|
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 [
|
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
|
-
|
17
|
-
|
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],
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: sensible-cinema
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 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-
|
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.
|
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/
|
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/
|
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.
|
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
|
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
|
-
*/
|