2 * Copyright (C) 2000 Rich Wareham <richwareham@users.sourceforge.net>
4 * This file is part of libdvdnav, a DVD navigation library.
6 * libdvdnav is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * libdvdnav is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with libdvdnav; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
29 #include "dvdnav/dvdnav.h"
30 #include <dvdread/nav_types.h>
31 #include <dvdread/ifo_types.h>
33 #include "vm/decoder.h"
35 #include "dvdnav_internal.h"
37 /* Navigation API calls */
39 dvdnav_status_t
dvdnav_still_skip(dvdnav_t
*this) {
40 pthread_mutex_lock(&this->vm_lock
);
41 this->position_current
.still
= 0;
42 pthread_mutex_unlock(&this->vm_lock
);
45 this->sync_wait_skip
= 1;
47 return DVDNAV_STATUS_OK
;
50 dvdnav_status_t
dvdnav_wait_skip(dvdnav_t
*this) {
52 this->sync_wait_skip
= 1;
54 return DVDNAV_STATUS_OK
;
57 dvdnav_status_t
dvdnav_get_number_of_titles(dvdnav_t
*this, int32_t *titles
) {
58 if (!this->vm
->vmgi
) {
59 printerr("Bad VM state.");
60 return DVDNAV_STATUS_ERR
;
63 (*titles
) = vm_get_vmgi(this->vm
)->tt_srpt
->nr_of_srpts
;
65 return DVDNAV_STATUS_OK
;
68 dvdnav_status_t
dvdnav_get_number_of_parts(dvdnav_t
*this, int32_t title
, int32_t *parts
) {
69 if (!this->vm
->vmgi
) {
70 printerr("Bad VM state.");
71 return DVDNAV_STATUS_ERR
;
73 if ((title
< 1) || (title
> vm_get_vmgi(this->vm
)->tt_srpt
->nr_of_srpts
) ) {
74 printerr("Passed a title number out of range.");
75 return DVDNAV_STATUS_ERR
;
78 (*parts
) = vm_get_vmgi(this->vm
)->tt_srpt
->title
[title
-1].nr_of_ptts
;
80 return DVDNAV_STATUS_OK
;
83 dvdnav_status_t
dvdnav_current_title_info(dvdnav_t
*this, int32_t *title
, int32_t *part
) {
86 pthread_mutex_lock(&this->vm_lock
);
87 if (!this->vm
->vtsi
|| !this->vm
->vmgi
) {
88 printerr("Bad VM state.");
89 pthread_mutex_unlock(&this->vm_lock
);
90 return DVDNAV_STATUS_ERR
;
93 printerr("Virtual DVD machine not started.");
94 pthread_mutex_unlock(&this->vm_lock
);
95 return DVDNAV_STATUS_ERR
;
97 if (!this->vm
->state
.pgc
) {
98 printerr("No current PGC.");
99 pthread_mutex_unlock(&this->vm_lock
);
100 return DVDNAV_STATUS_ERR
;
102 if ( (this->vm
->state
.domain
== VTSM_DOMAIN
)
103 || (this->vm
->state
.domain
== VMGM_DOMAIN
) ) {
104 /* Get current Menu ID: into *part. */
105 if(! vm_get_current_menu(this->vm
, part
)) {
106 pthread_mutex_unlock(&this->vm_lock
);
107 return DVDNAV_STATUS_ERR
;
111 pthread_mutex_unlock(&this->vm_lock
);
112 return DVDNAV_STATUS_OK
;
115 if (this->vm
->state
.domain
== VTS_DOMAIN
) {
116 retval
= vm_get_current_title_part(this->vm
, title
, part
);
117 pthread_mutex_unlock(&this->vm_lock
);
118 return retval
? DVDNAV_STATUS_OK
: DVDNAV_STATUS_ERR
;
120 printerr("Not in a title or menu.");
121 pthread_mutex_unlock(&this->vm_lock
);
122 return DVDNAV_STATUS_ERR
;
125 dvdnav_status_t
dvdnav_title_play(dvdnav_t
*this, int32_t title
) {
126 return dvdnav_part_play(this, title
, 1);
129 dvdnav_status_t
dvdnav_part_play(dvdnav_t
*this, int32_t title
, int32_t part
) {
132 pthread_mutex_lock(&this->vm_lock
);
133 if (!this->vm
->vmgi
) {
134 printerr("Bad VM state.");
135 pthread_mutex_unlock(&this->vm_lock
);
136 return DVDNAV_STATUS_ERR
;
138 if (!this->started
) {
139 /* don't report an error but be nice */
143 if (!this->vm
->state
.pgc
) {
144 printerr("No current PGC.");
145 pthread_mutex_unlock(&this->vm_lock
);
146 return DVDNAV_STATUS_ERR
;
148 if((title
< 1) || (title
> this->vm
->vmgi
->tt_srpt
->nr_of_srpts
)) {
149 printerr("Title out of range.");
150 pthread_mutex_unlock(&this->vm_lock
);
151 return DVDNAV_STATUS_ERR
;
153 if((part
< 1) || (part
> this->vm
->vmgi
->tt_srpt
->title
[title
-1].nr_of_ptts
)) {
154 printerr("Part out of range.");
155 pthread_mutex_unlock(&this->vm_lock
);
156 return DVDNAV_STATUS_ERR
;
159 retval
= vm_jump_title_part(this->vm
, title
, part
);
161 this->vm
->hop_channel
++;
162 pthread_mutex_unlock(&this->vm_lock
);
164 return retval
? DVDNAV_STATUS_OK
: DVDNAV_STATUS_ERR
;
167 dvdnav_status_t
dvdnav_part_play_auto_stop(dvdnav_t
*this, int32_t title
,
168 int32_t part
, int32_t parts_to_play
) {
169 /* FIXME: Implement auto-stop */
170 if (dvdnav_part_play(this, title
, part
) == DVDNAV_STATUS_OK
)
171 printerr("Not implemented yet.");
172 return DVDNAV_STATUS_ERR
;
175 dvdnav_status_t
dvdnav_time_play(dvdnav_t
*this, int32_t title
,
177 /* FIXME: Implement */
178 printerr("Not implemented yet.");
179 return DVDNAV_STATUS_ERR
;
182 dvdnav_status_t
dvdnav_stop(dvdnav_t
*this) {
183 pthread_mutex_lock(&this->vm_lock
);
184 this->vm
->stopped
= 1;
185 pthread_mutex_unlock(&this->vm_lock
);
186 return DVDNAV_STATUS_OK
;
189 dvdnav_status_t
dvdnav_go_up(dvdnav_t
*this) {
190 /* A nice easy function... delegate to the VM */
191 pthread_mutex_lock(&this->vm_lock
);
192 vm_jump_up(this->vm
);
193 pthread_mutex_unlock(&this->vm_lock
);
195 return DVDNAV_STATUS_OK
;