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
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 */
20
21 #ifndef DVDNAV_INTERNAL_H_INCLUDED
22 #define DVDNAV_INTERNAL_H_INCLUDED
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <unistd.h>
31 #include <limits.h>
32 #include <string.h>
33
34 #ifndef HAVE_GETTIMEOFDAY
35 # ifdef WIN32
36 # include <winsock.h>
37 struct timezone;
38 # else
39 # include <sys/time.h>
40 # endif
41 /* replacement gettimeofday implementation */
42 #include <sys/timeb.h>
dvdnav_private_gettimeofday(struct timeval * tv,void * tz)43 static inline int dvdnav_private_gettimeofday( struct timeval *tv, void *tz )
44 {
45 struct timeb t;
46 ftime( &t );
47 tv->tv_sec = t.time;
48 tv->tv_usec = t.millitm * 1000;
49 return 0;
50 }
51 #define gettimeofday(TV, TZ) dvdnav_private_gettimeofday((TV), (TZ))
52 #define HAVE_GETTIMEOFDAY 1
53 #endif
54
55 #ifndef HAVE_SNPRINTF
56 # ifdef HAVE__SNPRINTF
57 # define snprintf _snprintf
58 # define HAVE_SNPRINTF 1
59 # endif
60 #endif
61
62 #ifdef WIN32
63
64 /* pthread_mutex_* wrapper for win32 */
65 #include <windows.h>
66 #include <process.h>
67 typedef CRITICAL_SECTION pthread_mutex_t;
68 #define pthread_mutex_init(a, b) InitializeCriticalSection(a)
69 #define pthread_mutex_lock(a) EnterCriticalSection(a)
70 #define pthread_mutex_unlock(a) LeaveCriticalSection(a)
71 #define pthread_mutex_destroy(a)
72
73 #include <io.h> /* read() */
74 #define lseek64 _lseeki64
75
76 #else
77
78 #include <pthread.h>
79
80 #endif /* WIN32 */
81
82 /* Uncomment for VM command tracing */
83 /* #define TRACE */
84
85 #include "decoder.h"
86 #include "dvdnav.h"
87 #include "vm.h"
88 #include "vmcmd.h"
89
90 /* where should libdvdnav write its messages (stdout/stderr) */
91 #define MSG_OUT stdout
92
93 /* Maximum length of an error string */
94 #define MAX_ERR_LEN 255
95
96 /* Use the POSIX PATH_MAX if available */
97 #ifdef PATH_MAX
98 #define MAX_PATH_LEN PATH_MAX
99 #else
100 #define MAX_PATH_LEN 255 /* Arbitrary */
101 #endif
102
103 #ifndef DVD_VIDEO_LB_LEN
104 #define DVD_VIDEO_LB_LEN 2048
105 #endif
106
107 typedef struct read_cache_s read_cache_t;
108
109 /*
110 * These are defined here because they are
111 * not in ifo_types.h, they maybe one day
112 */
113
114 #ifndef audio_status_t
115 typedef struct {
116 #ifdef WORDS_BIGENDIAN
117 unsigned int available : 1;
118 unsigned int zero1 : 4;
119 unsigned int stream_number : 3;
120 uint8_t zero2;
121 #else
122 uint8_t zero2;
123 unsigned int stream_number : 3;
124 unsigned int zero1 : 4;
125 unsigned int available : 1;
126 #endif
127 } ATTRIBUTE_PACKED audio_status_t;
128 #endif
129
130 #ifndef spu_status_t
131 typedef struct {
132 #ifdef WORDS_BIGENDIAN
133 unsigned int available : 1;
134 unsigned int zero1 : 2;
135 unsigned int stream_number_4_3 : 5;
136 unsigned int zero2 : 3;
137 unsigned int stream_number_wide : 5;
138 unsigned int zero3 : 3;
139 unsigned int stream_number_letterbox : 5;
140 unsigned int zero4 : 3;
141 unsigned int stream_number_pan_scan : 5;
142 #else
143 unsigned int stream_number_pan_scan : 5;
144 unsigned int zero4 : 3;
145 unsigned int stream_number_letterbox : 5;
146 unsigned int zero3 : 3;
147 unsigned int stream_number_wide : 5;
148 unsigned int zero2 : 3;
149 unsigned int stream_number_4_3 : 5;
150 unsigned int zero1 : 2;
151 unsigned int available : 1;
152 #endif
153 } ATTRIBUTE_PACKED spu_status_t;
154 #endif
155
156 typedef struct dvdnav_vobu_s {
157 int32_t vobu_start; /* Logical Absolute. MAX needed is 0x300000 */
158 int32_t vobu_length;
159 int32_t blockN; /* Relative offset */
160 int32_t vobu_next; /* Relative offset */
161 } dvdnav_vobu_t;
162
163 /** The main DVDNAV type **/
164
165 struct dvdnav_s {
166 /* General data */
167 char path[MAX_PATH_LEN]; /* Path to DVD device/dir */
168 dvd_file_t *file; /* Currently opened file */
169
170 /* Position data */
171 vm_position_t position_next;
172 vm_position_t position_current;
173 dvdnav_vobu_t vobu;
174
175 /* NAV data */
176 pci_t pci;
177 dsi_t dsi;
178 uint32_t last_cmd_nav_lbn; /* detects when a command is issued on an already left NAV */
179
180 /* Flags */
181 int skip_still; /* Set when skipping a still */
182 int sync_wait; /* applications should wait till they are in sync with us */
183 int sync_wait_skip; /* Set when skipping wait state */
184 int spu_clut_changed; /* The SPU CLUT changed */
185 int started; /* vm_start has been called? */
186 int use_read_ahead; /* 1 - use read-ahead cache, 0 - don't */
187 int pgc_based; /* positioning works PGC based instead of PG based */
188
189 /* VM */
190 vm_t *vm;
191 pthread_mutex_t vm_lock;
192
193 /* Read-ahead cache */
194 read_cache_t *cache;
195
196 /* Errors */
197 char err_str[MAX_ERR_LEN];
198 };
199
200 /** USEFUL MACROS **/
201
202 /* printerr*() are often called when this is NULL. Avoid segfaults by replacing these with
203 * more common prints
204 */
205 #ifdef __GNUC__
206 #define printerrf(format, args...) \
207 do { \
208 if ( ! this ) fprintf(stderr, "Missing 'this' pointer while erroring:" format "\n", ## args); \
209 else snprintf(this->err_str, MAX_ERR_LEN, format, ## args); \
210 } while(0);
211 #else
212 #ifdef _MSC_VER
213 #define printerrf(str) snprintf(this->err_str, MAX_ERR_LEN, str);
214 #else
215 #define printerrf(...) \
216 do { \
217 if ( ! this ) { \
218 fprintf(stderr, "Missing 'this' pointer while erroring:"); \
219 fprintf(stderr, __VA_ARGS__); \
220 fprintf(stderr, "\n"); \
221 } else { \
222 snprintf(this->err_str, MAX_ERR_LEN, __VA_ARGS__); \
223 } \
224 } while(0);
225 #endif /* WIN32 */
226 #endif
227 #define printerr(str) \
228 do { \
229 if ( ! this ) { \
230 fprintf(stderr, "Missing 'this' pointer while erroring: %s\n", str); \
231 } else { \
232 strncpy(this->err_str, str, MAX_ERR_LEN); \
233 } \
234 } while(0);
235
236 #endif /* DVDNAV_INTERNAL_H_INCLUDED */
237