|
MythTV
0.26-pre
|
00001 /* 00002 * Copyright (C) 2000 Rich Wareham <richwareham@users.sourceforge.net> 00003 * 00004 * This file is part of libdvdnav, a DVD navigation library. 00005 * 00006 * libdvdnav is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * libdvdnav is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License along 00017 * with libdvdnav; if not, write to the Free Software Foundation, Inc., 00018 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00019 */ 00020 00021 #ifdef HAVE_CONFIG_H 00022 #include "config.h" 00023 #endif 00024 00025 #include <inttypes.h> 00026 #include <limits.h> 00027 #include <string.h> 00028 #include <sys/time.h> 00029 #include "dvdnav/dvdnav.h" 00030 #include <dvdread/nav_types.h> 00031 #include <dvdread/ifo_types.h> 00032 #include "remap.h" 00033 #include "vm/decoder.h" 00034 #include "vm/vm.h" 00035 #include "dvdnav_internal.h" 00036 00037 /* Navigation API calls */ 00038 00039 dvdnav_status_t dvdnav_still_skip(dvdnav_t *this) { 00040 pthread_mutex_lock(&this->vm_lock); 00041 this->position_current.still = 0; 00042 pthread_mutex_unlock(&this->vm_lock); 00043 this->skip_still = 1; 00044 this->sync_wait = 0; 00045 this->sync_wait_skip = 1; 00046 00047 return DVDNAV_STATUS_OK; 00048 } 00049 00050 dvdnav_status_t dvdnav_wait_skip(dvdnav_t *this) { 00051 this->sync_wait = 0; 00052 this->sync_wait_skip = 1; 00053 00054 return DVDNAV_STATUS_OK; 00055 } 00056 00057 dvdnav_status_t dvdnav_get_number_of_titles(dvdnav_t *this, int32_t *titles) { 00058 if (!this->vm->vmgi) { 00059 printerr("Bad VM state."); 00060 return DVDNAV_STATUS_ERR; 00061 } 00062 00063 (*titles) = vm_get_vmgi(this->vm)->tt_srpt->nr_of_srpts; 00064 00065 return DVDNAV_STATUS_OK; 00066 } 00067 00068 dvdnav_status_t dvdnav_get_number_of_parts(dvdnav_t *this, int32_t title, int32_t *parts) { 00069 if (!this->vm->vmgi) { 00070 printerr("Bad VM state."); 00071 return DVDNAV_STATUS_ERR; 00072 } 00073 if ((title < 1) || (title > vm_get_vmgi(this->vm)->tt_srpt->nr_of_srpts) ) { 00074 printerr("Passed a title number out of range."); 00075 return DVDNAV_STATUS_ERR; 00076 } 00077 00078 (*parts) = vm_get_vmgi(this->vm)->tt_srpt->title[title-1].nr_of_ptts; 00079 00080 return DVDNAV_STATUS_OK; 00081 } 00082 00083 dvdnav_status_t dvdnav_current_title_info(dvdnav_t *this, int32_t *title, int32_t *part) { 00084 int32_t retval; 00085 00086 pthread_mutex_lock(&this->vm_lock); 00087 if (!this->vm->vtsi || !this->vm->vmgi) { 00088 printerr("Bad VM state."); 00089 pthread_mutex_unlock(&this->vm_lock); 00090 return DVDNAV_STATUS_ERR; 00091 } 00092 if (!this->started) { 00093 printerr("Virtual DVD machine not started."); 00094 pthread_mutex_unlock(&this->vm_lock); 00095 return DVDNAV_STATUS_ERR; 00096 } 00097 if (!this->vm->state.pgc) { 00098 printerr("No current PGC."); 00099 pthread_mutex_unlock(&this->vm_lock); 00100 return DVDNAV_STATUS_ERR; 00101 } 00102 if ( (this->vm->state.domain == VTSM_DOMAIN) 00103 || (this->vm->state.domain == VMGM_DOMAIN) ) { 00104 /* Get current Menu ID: into *part. */ 00105 if(! vm_get_current_menu(this->vm, part)) { 00106 pthread_mutex_unlock(&this->vm_lock); 00107 return DVDNAV_STATUS_ERR; 00108 } 00109 if (*part > -1) { 00110 *title = 0; 00111 pthread_mutex_unlock(&this->vm_lock); 00112 return DVDNAV_STATUS_OK; 00113 } 00114 } 00115 if (this->vm->state.domain == VTS_DOMAIN) { 00116 retval = vm_get_current_title_part(this->vm, title, part); 00117 pthread_mutex_unlock(&this->vm_lock); 00118 return retval ? DVDNAV_STATUS_OK : DVDNAV_STATUS_ERR; 00119 } 00120 printerr("Not in a title or menu."); 00121 pthread_mutex_unlock(&this->vm_lock); 00122 return DVDNAV_STATUS_ERR; 00123 } 00124 00125 dvdnav_status_t dvdnav_current_title_program(dvdnav_t *this, int32_t *title, int32_t *pgcn, int32_t *pgn) { 00126 int32_t retval; 00127 int32_t part; 00128 00129 pthread_mutex_lock(&this->vm_lock); 00130 if (!this->vm->vtsi || !this->vm->vmgi) { 00131 printerr("Bad VM state."); 00132 pthread_mutex_unlock(&this->vm_lock); 00133 return DVDNAV_STATUS_ERR; 00134 } 00135 if (!this->started) { 00136 printerr("Virtual DVD machine not started."); 00137 pthread_mutex_unlock(&this->vm_lock); 00138 return DVDNAV_STATUS_ERR; 00139 } 00140 if (!this->vm->state.pgc) { 00141 printerr("No current PGC."); 00142 pthread_mutex_unlock(&this->vm_lock); 00143 return DVDNAV_STATUS_ERR; 00144 } 00145 if ( (this->vm->state.domain == VTSM_DOMAIN) 00146 || (this->vm->state.domain == VMGM_DOMAIN) ) { 00147 /* Get current Menu ID: into *part. */ 00148 if(! vm_get_current_menu(this->vm, &part)) { 00149 pthread_mutex_unlock(&this->vm_lock); 00150 return DVDNAV_STATUS_ERR; 00151 } 00152 if (part > -1) { 00153 *title = 0; 00154 *pgcn = this->vm->state.pgcN; 00155 *pgn = this->vm->state.pgN; 00156 pthread_mutex_unlock(&this->vm_lock); 00157 return DVDNAV_STATUS_OK; 00158 } 00159 } 00160 if (this->vm->state.domain == VTS_DOMAIN) { 00161 retval = vm_get_current_title_part(this->vm, title, &part); 00162 *pgcn = this->vm->state.pgcN; 00163 *pgn = this->vm->state.pgN; 00164 pthread_mutex_unlock(&this->vm_lock); 00165 return retval ? DVDNAV_STATUS_OK : DVDNAV_STATUS_ERR; 00166 } 00167 printerr("Not in a title or menu."); 00168 pthread_mutex_unlock(&this->vm_lock); 00169 return DVDNAV_STATUS_ERR; 00170 } 00171 00172 void dvdnav_first_play(dvdnav_t *this) { 00173 pthread_mutex_lock(&this->vm_lock); 00174 this->started = 0; 00175 vm_start(this->vm); 00176 this->started = 1; 00177 pthread_mutex_unlock(&this->vm_lock); 00178 } 00179 00180 dvdnav_status_t dvdnav_title_play(dvdnav_t *this, int32_t title) { 00181 return dvdnav_part_play(this, title, 1); 00182 } 00183 00184 dvdnav_status_t dvdnav_program_play(dvdnav_t *this, int32_t title, int32_t pgcn, int32_t pgn) { 00185 int32_t retval; 00186 00187 pthread_mutex_lock(&this->vm_lock); 00188 if (!this->vm->vmgi) { 00189 printerr("Bad VM state."); 00190 pthread_mutex_unlock(&this->vm_lock); 00191 return DVDNAV_STATUS_ERR; 00192 } 00193 if (!this->started) { 00194 /* don't report an error but be nice */ 00195 vm_start(this->vm); 00196 this->started = 1; 00197 } 00198 if (!this->vm->state.pgc) { 00199 printerr("No current PGC."); 00200 pthread_mutex_unlock(&this->vm_lock); 00201 return DVDNAV_STATUS_ERR; 00202 } 00203 if((title < 1) || (title > this->vm->vmgi->tt_srpt->nr_of_srpts)) { 00204 printerr("Title out of range."); 00205 pthread_mutex_unlock(&this->vm_lock); 00206 return DVDNAV_STATUS_ERR; 00207 } 00208 00209 retval = vm_jump_title_program(this->vm, title, pgcn, pgn); 00210 if (retval) 00211 this->vm->hop_channel++; 00212 pthread_mutex_unlock(&this->vm_lock); 00213 00214 return retval ? DVDNAV_STATUS_OK : DVDNAV_STATUS_ERR; 00215 } 00216 00217 dvdnav_status_t dvdnav_part_play(dvdnav_t *this, int32_t title, int32_t part) { 00218 int32_t retval; 00219 00220 pthread_mutex_lock(&this->vm_lock); 00221 if (!this->vm->vmgi) { 00222 printerr("Bad VM state."); 00223 pthread_mutex_unlock(&this->vm_lock); 00224 return DVDNAV_STATUS_ERR; 00225 } 00226 if (!this->started) { 00227 /* don't report an error but be nice */ 00228 vm_start(this->vm); 00229 this->started = 1; 00230 } 00231 if (!this->vm->state.pgc) { 00232 printerr("No current PGC."); 00233 pthread_mutex_unlock(&this->vm_lock); 00234 return DVDNAV_STATUS_ERR; 00235 } 00236 if((title < 1) || (title > this->vm->vmgi->tt_srpt->nr_of_srpts)) { 00237 printerr("Title out of range."); 00238 pthread_mutex_unlock(&this->vm_lock); 00239 return DVDNAV_STATUS_ERR; 00240 } 00241 if((part < 1) || (part > this->vm->vmgi->tt_srpt->title[title-1].nr_of_ptts)) { 00242 printerr("Part out of range."); 00243 pthread_mutex_unlock(&this->vm_lock); 00244 return DVDNAV_STATUS_ERR; 00245 } 00246 00247 retval = vm_jump_title_part(this->vm, title, part); 00248 if (retval) 00249 this->vm->hop_channel++; 00250 pthread_mutex_unlock(&this->vm_lock); 00251 00252 return retval ? DVDNAV_STATUS_OK : DVDNAV_STATUS_ERR; 00253 } 00254 00255 dvdnav_status_t dvdnav_part_play_auto_stop(dvdnav_t *this, int32_t title, 00256 int32_t part, int32_t parts_to_play) { 00257 /* FIXME: Implement auto-stop */ 00258 if (dvdnav_part_play(this, title, part) == DVDNAV_STATUS_OK) 00259 printerr("Not implemented yet."); 00260 return DVDNAV_STATUS_ERR; 00261 } 00262 00263 dvdnav_status_t dvdnav_time_play(dvdnav_t *this, int32_t title, 00264 uint64_t time) { 00265 /* FIXME: Implement */ 00266 printerr("Not implemented yet."); 00267 return DVDNAV_STATUS_ERR; 00268 } 00269 00270 dvdnav_status_t dvdnav_stop(dvdnav_t *this) { 00271 pthread_mutex_lock(&this->vm_lock); 00272 this->vm->stopped = 1; 00273 pthread_mutex_unlock(&this->vm_lock); 00274 return DVDNAV_STATUS_OK; 00275 } 00276 00277 dvdnav_status_t dvdnav_go_up(dvdnav_t *this) { 00278 /* A nice easy function... delegate to the VM */ 00279 pthread_mutex_lock(&this->vm_lock); 00280 vm_jump_up(this->vm); 00281 pthread_mutex_unlock(&this->vm_lock); 00282 00283 return DVDNAV_STATUS_OK; 00284 }
1.7.6.1