1 #include "mpeg3private.h"
2 #include "mpeg3protos.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
);
15 fs
->buffer_position
= -0xffff;
16 fs
->css
= mpeg3_new_css();
17 strcpy(fs
->path
, path
);
21 int mpeg3_delete_fs(mpeg3_fs_t
*fs
)
23 mpeg3_delete_css(fs
->css
);
29 int mpeg3_copy_fs(mpeg3_fs_t
*dst
, mpeg3_fs_t
*src
)
31 strcpy(dst
->path
, src
->path
);
32 dst
->current_byte
= 0;
36 int64_t mpeg3io_get_total_bytes(mpeg3_fs_t
*fs
)
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
)
54 if(stat64(path
, &st
) < 0) return 0;
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");
70 fs
->total_bytes
= mpeg3io_get_total_bytes(fs
);
79 fs
->buffer_position
= -0xffff;
83 int mpeg3io_close_file(mpeg3_fs_t
*fs
)
85 if(fs
->fd
) fclose(fs
->fd
);
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
;
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,
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
;
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
;
173 // Sequential forward buffer or random seek
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",
189 * fs->buffer_position,
204 void mpeg3io_complete_path(char *complete_path
, char *path
)
208 char current_dir
[MPEG3_STRLEN
];
209 getcwd(current_dir
, MPEG3_STRLEN
);
210 sprintf(complete_path
, "%s/%s", current_dir
, path
);
213 strcpy(complete_path
, path
);
216 int mpeg3io_device(char *path
, char *device
)
218 struct stat64 file_st
, device_st
;
222 if(stat64(path
, &file_st
) < 0)
224 perror("mpeg3io_device");
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
);
243 void mpeg3io_get_directory(char *directory
, char *path
)
245 char *ptr
= strrchr(path
, '/');
249 for(i
= 0; i
< ptr
- path
; i
++)
251 directory
[i
] = path
[i
];
257 void mpeg3io_get_filename(char *filename
, char *path
)
259 char *ptr
= strrchr(path
, '/');
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
);