1 /*
2  * Copyright (C) 2001-2004 Rich Wareham <richwareham@users.sourceforge.net>
3  *
4  * This file is part of libdvdnav, a DVD navigation library.
5  *
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.
10  *
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.
15  *
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.
19  */
20 
21 #ifndef LIBDVDNAV_DVDNAV_INTERNAL_H
22 #define LIBDVDNAV_DVDNAV_INTERNAL_H
23 
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27 
28 #ifdef _WIN32
29 
30 /* pthread_mutex_* wrapper for win32 */
31 #include <windows.h>
32 #include <process.h>
33 typedef CRITICAL_SECTION pthread_mutex_t;
34 #define pthread_mutex_init(a, b) InitializeCriticalSection(a)
35 #define pthread_mutex_lock(a)    EnterCriticalSection(a)
36 #define pthread_mutex_unlock(a)  LeaveCriticalSection(a)
37 #define pthread_mutex_destroy(a) DeleteCriticalSection(a)
38 
39 #ifndef HAVE_GETTIMEOFDAY
40 /* replacement gettimeofday implementation */
41 #include <sys/timeb.h>
_private_gettimeofday(struct timeval * tv,void * tz)42 static inline int _private_gettimeofday( struct timeval *tv, void *tz )
43 {
44   struct timeb t;
45   ftime( &t );
46   tv->tv_sec = t.time;
47   tv->tv_usec = t.millitm * 1000;
48   return 0;
49 }
50 #define gettimeofday(TV, TZ) _private_gettimeofday((TV), (TZ))
51 #endif
52 
53 #include <io.h> /* read() */
54 #define lseek64 _lseeki64
55 
56 #else
57 
58 #include <pthread.h>
59 
60 #endif /* _WIN32 */
61 
62 #ifdef __ANDROID__
63 # undef  lseek
64 # define lseek lseek64
65 # undef  off_t
66 # define off_t off64_t
67 #endif
68 
69 /* where should libdvdnav write its messages (stdout/stderr) */
70 #define MSG_OUT stderr
71 
72 /* Maximum length of an error string */
73 #define MAX_ERR_LEN 255
74 
75 #ifndef DVD_VIDEO_LB_LEN
76 #define DVD_VIDEO_LB_LEN 2048
77 #endif
78 
79 typedef enum {
80   DSI_ILVU_PRE   = 1 << 15, /* set during the last 3 VOBU preceeding an interleaved block. */
81   DSI_ILVU_BLOCK = 1 << 14, /* set for all VOBU in an interleaved block */
82   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 */
83   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 */
84   DSI_ILVU_MASK  = 0xf000
85 } DSI_ILVU;
86 
87 typedef struct read_cache_s read_cache_t;
88 
89 /*
90  * These are defined here because they are
91  * not in ifo_types.h, they maybe one day
92  */
93 
94 #ifndef audio_status_t
95 typedef struct {
96 #ifdef WORDS_BIGENDIAN
97   unsigned int available     : 1;
98   unsigned int zero1         : 4;
99   unsigned int stream_number : 3;
100   uint8_t zero2;
101 #else
102   uint8_t zero2;
103   unsigned int stream_number : 3;
104   unsigned int zero1         : 4;
105   unsigned int available     : 1;
106 #endif
107 } ATTRIBUTE_PACKED audio_status_t;
108 #endif
109 
110 #ifndef spu_status_t
111 typedef struct {
112 #ifdef WORDS_BIGENDIAN
113   unsigned int available               : 1;
114   unsigned int zero1                   : 2;
115   unsigned int stream_number_4_3       : 5;
116   unsigned int zero2                   : 3;
117   unsigned int stream_number_wide      : 5;
118   unsigned int zero3                   : 3;
119   unsigned int stream_number_letterbox : 5;
120   unsigned int zero4                   : 3;
121   unsigned int stream_number_pan_scan  : 5;
122 #else
123   unsigned int stream_number_pan_scan  : 5;
124   unsigned int zero4                   : 3;
125   unsigned int stream_number_letterbox : 5;
126   unsigned int zero3                   : 3;
127   unsigned int stream_number_wide      : 5;
128   unsigned int zero2                   : 3;
129   unsigned int stream_number_4_3       : 5;
130   unsigned int zero1                   : 2;
131   unsigned int available               : 1;
132 #endif
133 } ATTRIBUTE_PACKED spu_status_t;
134 #endif
135 
136 /*
137  * Describes a given time, and the closest sector, vobu and tmap index
138  */
139 typedef struct {
140   uint64_t            time;
141   uint32_t            sector;
142   uint32_t            vobu_idx;
143   int32_t             tmap_idx;
144 } dvdnav_pos_data_t;
145 
146 /*
147  * Encapsulates cell data
148  */
149 typedef struct {
150   int32_t             idx;
151   dvdnav_pos_data_t   *bgn;
152   dvdnav_pos_data_t   *end;
153 } dvdnav_cell_data_t;
154 
155 /*
156  * Encapsulates common variables used by internal functions of jump_to_time
157  */
158 typedef struct {
159   vobu_admap_t        *admap;
160   int32_t             admap_len;
161   vts_tmap_t          *tmap;
162   int32_t             tmap_len;
163   int32_t             tmap_interval;
164 } dvdnav_jump_args_t;
165 
166 /*
167  * Utility constants for jump_to_time
168  */
169 #define TMAP_IDX_EDGE_BGN  -1
170 #define TMAP_IDX_EDGE_END  -2
171 #define JUMP_MODE_TIME_AFTER 1
172 #define JUMP_MODE_TIME_DEFAULT 0
173 #define JUMP_MODE_TIME_BEFORE -1
174 
175 typedef struct dvdnav_vobu_s {
176   int32_t vobu_start;  /* Logical Absolute. MAX needed is 0x300000 */
177   int32_t vobu_length;
178   int32_t blockN;      /* Relative offset */
179   int32_t vobu_next;   /* Relative offset */
180 } dvdnav_vobu_t;
181 
182 /** The main DVDNAV type **/
183 
184 struct dvdnav_s {
185   /* General data */
186   char       *path;               /* Path to DVD device/dir */
187   dvd_file_t *file;               /* Currently opened file */
188 
189   /* Position data */
190   vm_position_t position_next;
191   vm_position_t position_current;
192   dvdnav_vobu_t vobu;
193 
194   /* NAV data */
195   pci_t pci;
196   dsi_t dsi;
197   uint32_t last_cmd_nav_lbn;      /* detects when a command is issued on an already left NAV */
198 
199   /* Flags */
200   int skip_still;                 /* Set when skipping a still */
201   int sync_wait;                  /* applications should wait till they are in sync with us */
202   int sync_wait_skip;             /* Set when skipping wait state */
203   int spu_clut_changed;           /* The SPU CLUT changed */
204   int started;                    /* vm_start has been called? */
205   int use_read_ahead;             /* 1 - use read-ahead cache, 0 - don't */
206   int pgc_based;                  /* positioning works PGC based instead of PG based */
207   int cur_cell_time;              /* time expired since the beginning of the current cell, read from the dsi */
208 
209   /* VM */
210   vm_t *vm;
211   pthread_mutex_t vm_lock;
212 
213   /* private context and logger*/
214   void *priv;
215   dvdnav_logger_cb logcb;
216 
217   /* Read-ahead cache */
218   read_cache_t *cache;
219 
220   /* Errors */
221   char err_str[MAX_ERR_LEN];
222 };
223 
224 /** HELPER FUNCTIONS **/
225 
226 /* converts a dvd_time_t to PTS ticks */
227 int64_t dvdnav_convert_time(dvd_time_t *time);
228 
229 /** USEFUL MACROS **/
230 
231 #ifdef __GNUC__
232 #define printerrf(format, args...) \
233     do { if (this) snprintf(this->err_str, MAX_ERR_LEN, format, ## args); } while (0)
234 #else
235 #ifdef _MSC_VER
236 #define printerrf(str) \
237     do { if (this) snprintf(this->err_str, MAX_ERR_LEN, str); } while (0)
238 #else
239 #define printerrf(...) \
240     do { if (this) snprintf(this->err_str, MAX_ERR_LEN, __VA_ARGS__); } while (0)
241 #endif /* _MSC_VER */
242 #endif
243 #define printerr(str) \
244     do { if (this) strncpy(this->err_str, str, MAX_ERR_LEN - 1); } while (0)
245 
246 #endif /* LIBDVDNAV_DVDNAV_INTERNAL_H */
247