r125: This commit was manufactured by cvs2svn to create tag 'r1_1_7-last'.
[cinelerra_cv/mob.git] / hvirtual / libmpeg3 / mpeg3io.c
blobd8c00d22f67bd78d7ecc266aa5b65d1331969087
1 #include "mpeg3private.h"
2 #include "mpeg3protos.h"
4 #include <mntent.h>
5 #include <stdint.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <sys/stat.h>
10 mpeg3_fs_t* mpeg3_new_fs(char *path)
12 mpeg3_fs_t *fs = calloc(1, sizeof(mpeg3_fs_t));
13 fs->buffer = calloc(1, MPEG3_IO_SIZE);
14 // Force initial read
15 fs->buffer_position = -0xffff;
16 fs->css = mpeg3_new_css();
17 strcpy(fs->path, path);
18 return fs;
21 int mpeg3_delete_fs(mpeg3_fs_t *fs)
23 mpeg3_delete_css(fs->css);
24 free(fs->buffer);
25 free(fs);
26 return 0;
29 int mpeg3_copy_fs(mpeg3_fs_t *dst, mpeg3_fs_t *src)
31 strcpy(dst->path, src->path);
32 dst->current_byte = 0;
33 return 0;
36 int64_t mpeg3io_get_total_bytes(mpeg3_fs_t *fs)
38 struct stat64 ostat;
39 stat64(fs->path, &ostat);
40 fs->total_bytes = ostat.st_size;
41 return fs->total_bytes;
44 * fseek(fs->fd, 0, SEEK_END);
45 * fs->total_bytes = ftell(fs->fd);
46 * fseek(fs->fd, 0, SEEK_SET);
47 * return fs->total_bytes;
51 int64_t mpeg3io_path_total_bytes(char *path)
53 struct stat64 st;
54 if(stat64(path, &st) < 0) return 0;
55 return st.st_size;
58 int mpeg3io_open_file(mpeg3_fs_t *fs)
60 /* Need to perform authentication before reading a single byte. */
61 mpeg3_get_keys(fs->css, fs->path);
63 //printf("mpeg3io_open_file 1 %s\n", fs->path);
64 if(!(fs->fd = fopen64(fs->path, "rb")))
66 perror("mpeg3io_open_file");
67 return 1;
70 fs->total_bytes = mpeg3io_get_total_bytes(fs);
72 if(!fs->total_bytes)
74 fclose(fs->fd);
75 return 1;
78 fs->current_byte = 0;
79 fs->buffer_position = -0xffff;
80 return 0;
83 int mpeg3io_close_file(mpeg3_fs_t *fs)
85 if(fs->fd) fclose(fs->fd);
86 fs->fd = 0;
87 return 0;
90 int mpeg3io_read_data(unsigned char *buffer, long bytes, mpeg3_fs_t *fs)
92 int result = 0, i, fragment_size;
94 //printf("mpeg3io_read_data 1 %d\n", bytes);
95 for(i = 0; bytes > 0 && !result; )
97 result = mpeg3io_sync_buffer(fs);
99 fragment_size = MPEG3_IO_SIZE;
101 if(fragment_size > bytes) fragment_size = bytes;
103 if(fs->buffer_offset + fragment_size > fs->buffer_size)
104 fragment_size = fs->buffer_size - fs->buffer_offset;
106 memcpy(buffer + i, fs->buffer + fs->buffer_offset, fragment_size);
108 fs->buffer_offset += fragment_size;
109 fs->current_byte += fragment_size;
110 i += fragment_size;
111 bytes -= fragment_size;
112 //printf("mpeg3io_read_data 10 %d\n", bytes);
115 //printf("mpeg3io_read_data 100 %d\n", bytes);
116 return (result && bytes);
119 int mpeg3io_seek(mpeg3_fs_t *fs, int64_t byte)
121 //printf("mpeg3io_seek 1 %llx\n", byte);
122 fs->current_byte = byte;
123 return (fs->current_byte < 0) || (fs->current_byte > fs->total_bytes);
126 int mpeg3io_seek_relative(mpeg3_fs_t *fs, long bytes)
128 fs->current_byte += bytes;
129 return (fs->current_byte < 0) || (fs->current_byte > fs->total_bytes);
132 void mpeg3io_read_buffer(mpeg3_fs_t *fs)
134 // Sequential reverse buffer
135 if(fs->current_byte == fs->buffer_position - 1)
137 fs->buffer_position = fs->current_byte - MPEG3_IO_SIZE + 1;
138 if(fs->buffer_position < 0) fs->buffer_position = 0;
140 fs->buffer_size = fs->current_byte - fs->buffer_position + 1;
141 fs->buffer_offset = fs->buffer_size - 1;
143 //printf("mpeg3io_read_buffer 1 %x %x\n", fs->current_byte, fs->buffer_position);
144 fseeko64(fs->fd, fs->buffer_position, SEEK_SET);
145 //printf("mpeg3io_read_buffer 10\n");
146 fs->buffer_size = fread(fs->buffer, 1, fs->buffer_size, fs->fd);
147 //printf("mpeg3io_read_buffer 100\n");
149 else
150 // Sequential forward buffer or random seek
152 int result;
153 fs->buffer_position = fs->current_byte;
154 fs->buffer_offset = 0;
156 //printf("mpeg3io_read_buffer 200\n");
157 result = fseeko64(fs->fd, fs->buffer_position, SEEK_SET);
158 //printf("mpeg3io_read_buffer 210\n");
159 fs->buffer_size = fread(fs->buffer, 1, MPEG3_IO_SIZE, fs->fd);
160 //printf("mpeg3io_read_buffer 220\n");
162 * printf(__FUNCTION__ " 2 result=%d ftell=%llx buffer_position=%llx %02x%02x%02x%02x%02x%02x%02x%02x %02x%02x\n",
163 * result,
164 * ftello64(fs->fd),
165 * fs->buffer_position,
166 * fs->buffer[0x0],
167 * fs->buffer[0x1],
168 * fs->buffer[0x2],
169 * fs->buffer[0x3],
170 * fs->buffer[0x4],
171 * fs->buffer[0x5],
172 * fs->buffer[0x6],
173 * fs->buffer[0x7],
174 * fs->buffer[0x12],
175 * fs->buffer[0x13]);
180 void mpeg3io_complete_path(char *complete_path, char *path)
182 if(path[0] != '/')
184 char current_dir[MPEG3_STRLEN];
185 getcwd(current_dir, MPEG3_STRLEN);
186 sprintf(complete_path, "%s/%s", current_dir, path);
188 else
189 strcpy(complete_path, path);
192 int mpeg3io_device(char *path, char *device)
194 struct stat64 file_st, device_st;
195 struct mntent *mnt;
196 FILE *fp;
198 if(stat64(path, &file_st) < 0)
200 perror("mpeg3io_device");
201 return 1;
204 fp = setmntent(MOUNTED, "r");
205 while(fp && (mnt = getmntent(fp)))
207 if(stat64(mnt->mnt_fsname, &device_st) < 0) continue;
208 if(device_st.st_rdev == file_st.st_dev)
210 strncpy(device, mnt->mnt_fsname, MPEG3_STRLEN);
211 break;
214 endmntent(fp);
216 return 0;
219 void mpeg3io_get_directory(char *directory, char *path)
221 char *ptr = strrchr(path, '/');
222 if(ptr)
224 int i;
225 for(i = 0; i < ptr - path; i++)
227 directory[i] = path[i];
229 directory[i] = 0;
233 void mpeg3io_get_filename(char *filename, char *path)
235 char *ptr = strrchr(path, '/');
236 if(!ptr)
237 ptr = path;
238 else
239 ptr++;
241 strcpy(filename, ptr);
244 void mpeg3io_joinpath(char *title_path, char *directory, char *new_filename)
246 sprintf(title_path, "%s/%s", directory, new_filename);
250 /* Find end of next 4 byte code */
251 int mpeg3io_next_code(mpeg3_fs_t *fs, uint32_t code, int count)
253 uint32_t header = 0;
255 while(header != code &&
256 !mpeg3io_eof(fs) &&
257 count > 0)
259 header <<= 8;
260 header |= mpeg3io_read_char(fs);
261 count--;
264 return mpeg3io_eof(fs) || count <= 0;
267 /* Find start of previous 4 byte code */
268 int mpeg3io_prev_code(mpeg3_fs_t *fs, uint32_t code, int count)
270 uint32_t header = 0;
271 while(header != code &&
272 !mpeg3io_bof(fs) &&
273 count > 0)
275 mpeg3io_seek_relative(fs, -1);
276 header >>= 8;
277 header |= ((uint32_t)mpeg3io_read_char(fs)) << 24;
278 //printf("mpeg3io_prev_code %08x\n", header);
279 mpeg3io_seek_relative(fs, -1);
280 count--;
283 return mpeg3io_bof(fs) || count <= 0;