low pri planned fixes
[cinelerra_cv/ct.git] / libmpeg3 / mpeg3io.c
blobb7d9034734aac9a3607f00c670064a290f98c711
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, int64_t bytes, mpeg3_fs_t *fs)
92 int result = 0, i, fragment_size;
93 //printf("mpeg3io_read_data 1 %d\n", bytes);
95 for(i = 0; bytes > 0 && !result; )
97 result = mpeg3io_sync_buffer(fs);
98 //printf("mpeg3io_read_data 2\n");
100 fragment_size = MPEG3_IO_SIZE;
102 if(fragment_size > bytes) fragment_size = bytes;
104 if(fs->buffer_offset + fragment_size > fs->buffer_size)
105 fragment_size = fs->buffer_size - fs->buffer_offset;
107 memcpy(buffer + i, fs->buffer + fs->buffer_offset, fragment_size);
109 fs->buffer_offset += fragment_size;
110 fs->current_byte += fragment_size;
111 i += fragment_size;
112 bytes -= fragment_size;
113 //printf("mpeg3io_read_data 10 %d\n", bytes);
116 //printf("mpeg3io_read_data 100 %d\n", bytes);
117 return (result && bytes);
120 int mpeg3io_seek(mpeg3_fs_t *fs, int64_t byte)
122 //printf("mpeg3io_seek 1 %lld\n", byte);
123 fs->current_byte = byte;
124 return (fs->current_byte < 0) || (fs->current_byte > fs->total_bytes);
127 int mpeg3io_seek_relative(mpeg3_fs_t *fs, int64_t bytes)
129 //printf("mpeg3io_seek_relative 1 %lld\n", bytes);
130 fs->current_byte += bytes;
131 return (fs->current_byte < 0) || (fs->current_byte > fs->total_bytes);
135 void mpeg3io_read_buffer(mpeg3_fs_t *fs)
137 // Special case for sequential reverse buffer.
138 // This is only used for searching for previous codes.
139 // Here we move a full half buffer backwards since the search normally
140 // goes backwards and then forwards a little bit.
141 if(fs->current_byte < fs->buffer_position &&
142 fs->current_byte >= fs->buffer_position - MPEG3_IO_SIZE / 2)
144 int64_t new_buffer_position = fs->current_byte - MPEG3_IO_SIZE / 2;
145 int64_t new_buffer_size = MIN(fs->buffer_size + MPEG3_IO_SIZE / 2,
146 MPEG3_IO_SIZE);
147 if(new_buffer_position < 0)
149 new_buffer_size += new_buffer_position;
150 new_buffer_position = 0;
153 // Shift existing buffer forward and calculate amount of new data needed.
154 int remainder = new_buffer_position + new_buffer_size - fs->buffer_position;
155 if(remainder < 0) remainder = 0;
156 int remainder_start = new_buffer_size - remainder;
157 if(remainder)
159 memmove(fs->buffer + remainder_start, fs->buffer, remainder);
164 fseeko64(fs->fd, new_buffer_position, SEEK_SET);
165 fread(fs->buffer, 1, remainder_start, fs->fd);
168 fs->buffer_position = new_buffer_position;
169 fs->buffer_size = new_buffer_size;
170 fs->buffer_offset = fs->current_byte - fs->buffer_position;
172 else
173 // Sequential forward buffer or random seek
175 int result;
176 fs->buffer_position = fs->current_byte;
177 fs->buffer_offset = 0;
179 result = fseeko64(fs->fd, fs->buffer_position, SEEK_SET);
180 //printf("mpeg3io_read_buffer 2 %llx %llx\n", fs->buffer_position, ftell(fs->fd));
181 fs->buffer_size = fread(fs->buffer, 1, MPEG3_IO_SIZE, fs->fd);
186 * printf(__FUNCTION__ " 2 result=%d ftell=%llx buffer_position=%llx %02x%02x%02x%02x%02x%02x%02x%02x %02x%02x\n",
187 * result,
188 * ftello64(fs->fd),
189 * fs->buffer_position,
190 * fs->buffer[0x0],
191 * fs->buffer[0x1],
192 * fs->buffer[0x2],
193 * fs->buffer[0x3],
194 * fs->buffer[0x4],
195 * fs->buffer[0x5],
196 * fs->buffer[0x6],
197 * fs->buffer[0x7],
198 * fs->buffer[0x12],
199 * fs->buffer[0x13]);
204 void mpeg3io_complete_path(char *complete_path, char *path)
206 if(path[0] != '/')
208 char current_dir[MPEG3_STRLEN];
209 getcwd(current_dir, MPEG3_STRLEN);
210 sprintf(complete_path, "%s/%s", current_dir, path);
212 else
213 strcpy(complete_path, path);
216 int mpeg3io_device(char *path, char *device)
218 struct stat64 file_st, device_st;
219 struct mntent *mnt;
220 FILE *fp;
222 if(stat64(path, &file_st) < 0)
224 perror("mpeg3io_device");
225 return 1;
228 fp = setmntent(MOUNTED, "r");
229 while(fp && (mnt = getmntent(fp)))
231 if(stat64(mnt->mnt_fsname, &device_st) < 0) continue;
232 if(device_st.st_rdev == file_st.st_dev)
234 strncpy(device, mnt->mnt_fsname, MPEG3_STRLEN);
235 break;
238 endmntent(fp);
240 return 0;
243 void mpeg3io_get_directory(char *directory, char *path)
245 char *ptr = strrchr(path, '/');
246 if(ptr)
248 int i;
249 for(i = 0; i < ptr - path; i++)
251 directory[i] = path[i];
253 directory[i] = 0;
257 void mpeg3io_get_filename(char *filename, char *path)
259 char *ptr = strrchr(path, '/');
260 if(!ptr)
261 ptr = path;
262 else
263 ptr++;
265 strcpy(filename, ptr);
268 void mpeg3io_joinpath(char *title_path, char *directory, char *new_filename)
270 sprintf(title_path, "%s/%s", directory, new_filename);