MythTV  0.26-pre
navigation.c
Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends