1 /*
2 * GPAC - Multimedia Framework C SDK
3 *
4 * Authors: Jean Le Feuvre
5 * Copyright (c) Telecom ParisTech 2000-2019
6 * All rights reserved
7 *
8 * This file is part of GPAC / ISO Media File Format sub-project
9 *
10 * GPAC is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU Lesser General Public License as published by
12 * the Free Software Foundation; either version 2, or (at your option)
13 * any later version.
14 *
15 * GPAC is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; see the file COPYING. If not, write to
22 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 */
25
26 #include <gpac/internal/isomedia_dev.h>
27 #include <gpac/network.h>
28
29 #ifndef GPAC_DISABLE_ISOM
30
31
gf_isom_datamap_del(GF_DataMap * ptr)32 void gf_isom_datamap_del(GF_DataMap *ptr)
33 {
34 if (!ptr) return;
35
36 if (ptr->szName) gf_free(ptr->szName);
37
38 //then delete the structure itself....
39 switch (ptr->type) {
40 //file-based
41 case GF_ISOM_DATA_FILE:
42 case GF_ISOM_DATA_MEM:
43 gf_isom_fdm_del((GF_FileDataMap *)ptr);
44 break;
45 case GF_ISOM_DATA_FILE_MAPPING:
46 gf_isom_fmo_del((GF_FileMappingDataMap *)ptr);
47 break;
48 default:
49 if (ptr->bs) gf_bs_del(ptr->bs);
50 gf_free(ptr);
51 break;
52 }
53 }
54
55 //Close a data entry
gf_isom_datamap_close(GF_MediaInformationBox * minf)56 void gf_isom_datamap_close(GF_MediaInformationBox *minf)
57 {
58 GF_DataEntryBox *ent = NULL;
59 if (!minf || !minf->dataHandler) return;
60
61 if (minf->dataInformation && minf->dataInformation->dref) {
62 ent = (GF_DataEntryBox*)gf_list_get(minf->dataInformation->dref->child_boxes, minf->dataEntryIndex - 1);
63 }
64
65 //if ent NULL, the data entry was not used (smooth)
66 if (ent == NULL) return;
67
68 //self contained, do nothing
69 switch (ent->type) {
70 case GF_ISOM_BOX_TYPE_URL:
71 case GF_ISOM_BOX_TYPE_URN:
72 if (ent->flags == 1) return;
73 break;
74 default:
75 return;
76 }
77
78 //finally close it
79 gf_isom_datamap_del(minf->dataHandler);
80 minf->dataHandler = NULL;
81 }
82
83 /*cf below, we disable filedatamap since it tricks mem usage on w32*/
84 #if 0
85 static Bool IsLargeFile(char *path)
86 {
87 #ifndef _WIN32_WCE
88 FILE *stream;
89 s64 size;
90 stream = gf_fopen(path, "rb");
91 if (!stream) return 0;
92 size = gf_fsize(stream);
93 gf_fclose(stream);
94 if (size == -1L) return 0;
95 if (size > 0xFFFFFFFF) return 1;
96 #endif
97 return 0;
98 }
99 #endif
100
101
102 //Special constructor, we need some error feedback...
103
gf_isom_datamap_new(const char * location,const char * parentPath,u8 mode,GF_DataMap ** outDataMap)104 GF_Err gf_isom_datamap_new(const char *location, const char *parentPath, u8 mode, GF_DataMap **outDataMap)
105 {
106 Bool extern_file;
107 char *sPath;
108 *outDataMap = NULL;
109
110 //if nothing specified, this is a MEMORY data map
111 if (!location) {
112 *outDataMap = gf_isom_fdm_new(location, GF_ISOM_DATA_MAP_WRITE);
113 if (!(*outDataMap)) {
114 return GF_IO_ERR;
115 }
116 return GF_OK;
117 }
118 //we need a temp file ...
119 if (!strcmp(location, "mp4_tmp_edit")) {
120 #ifndef GPAC_DISABLE_ISOM_WRITE
121 *outDataMap = gf_isom_fdm_new_temp(parentPath);
122 if (! (*outDataMap)) {
123 return GF_IO_ERR;
124 }
125 return GF_OK;
126 #else
127 return GF_NOT_SUPPORTED;
128 #endif
129 } else if (!strncmp(location, "gmem://", 7) || !strncmp(location, "gfio://", 7)) {
130 *outDataMap = gf_isom_fdm_new(location, GF_ISOM_DATA_MAP_READ);
131 if (! (*outDataMap)) {
132 return GF_IO_ERR;
133 }
134 return GF_OK;
135 } else if (!strcmp(location, "_gpac_isobmff_redirect")) {
136 *outDataMap = gf_isom_fdm_new(location, mode);
137 if (! (*outDataMap)) {
138 return GF_IO_ERR;
139 }
140 return GF_OK;
141 }
142
143 extern_file = !gf_url_is_local(location);
144
145 if (mode == GF_ISOM_DATA_MAP_EDIT) {
146 //we need a local file for edition!!!
147 if (extern_file) return GF_ISOM_INVALID_MODE;
148 //OK, switch back to READ mode
149 mode = GF_ISOM_DATA_MAP_READ;
150 }
151
152 //TEMP: however, only support for file right now (we'd have to add some callback functions at some point)
153 if (extern_file) {
154 return GF_NOT_SUPPORTED;
155 }
156
157 sPath = gf_url_concatenate(parentPath, location);
158 if (sPath == NULL) {
159 return GF_URL_ERROR;
160 }
161
162 if (mode == GF_ISOM_DATA_MAP_READ_ONLY) {
163 mode = GF_ISOM_DATA_MAP_READ;
164 /*It seems win32 file mapping is reported in prog mem usage -> large increases of occupancy. Should not be a pb
165 but unless you want mapping, only regular IO will be used...*/
166 #if 0
167 if (IsLargeFile(sPath)) {
168 *outDataMap = gf_isom_fdm_new(sPath, mode);
169 } else {
170 *outDataMap = gf_isom_fmo_new(sPath, mode);
171 }
172 #else
173 *outDataMap = gf_isom_fdm_new(sPath, mode);
174 #endif
175 } else {
176 *outDataMap = gf_isom_fdm_new(sPath, mode);
177 if (*outDataMap) {
178 (*outDataMap)->szName = sPath;
179 sPath = NULL;
180 }
181 }
182
183 if (sPath) {
184 gf_free(sPath);
185 }
186 if (! (*outDataMap)) {
187 return GF_URL_ERROR;
188 }
189
190 return GF_OK;
191 }
192
193 //Open a data entry of a track
194 //Edit is used to switch between original and edition file
gf_isom_datamap_open(GF_MediaBox * mdia,u32 dataRefIndex,u8 Edit)195 GF_Err gf_isom_datamap_open(GF_MediaBox *mdia, u32 dataRefIndex, u8 Edit)
196 {
197 GF_DataEntryBox *ent;
198 GF_MediaInformationBox *minf;
199 u32 SelfCont, count;
200 GF_Err e = GF_OK;
201 if ((mdia == NULL) || (! mdia->information) || !dataRefIndex)
202 return GF_ISOM_INVALID_MEDIA;
203
204 minf = mdia->information;
205 if (!minf->dataInformation || !minf->dataInformation->dref)
206 return GF_ISOM_INVALID_MEDIA;
207
208 count = gf_list_count(minf->dataInformation->dref->child_boxes);
209 if (!count) {
210 SelfCont = 1;
211 ent = NULL;
212 } else {
213 if (dataRefIndex > gf_list_count(minf->dataInformation->dref->child_boxes))
214 return GF_BAD_PARAM;
215
216 ent = (GF_DataEntryBox*)gf_list_get(minf->dataInformation->dref->child_boxes, dataRefIndex - 1);
217 if (ent == NULL) return GF_ISOM_INVALID_MEDIA;
218
219 //if the current dataEntry is the desired one, and not self contained, return
220 if ((minf->dataEntryIndex == dataRefIndex) && (ent->flags != 1)) {
221 return GF_OK;
222 }
223
224 SelfCont = 0;
225 switch (ent->type) {
226 case GF_ISOM_BOX_TYPE_URL:
227 case GF_ISOM_BOX_TYPE_URN:
228 if (ent->flags == 1) SelfCont = 1;
229 break;
230 default:
231 SelfCont = 1;
232 break;
233 }
234 }
235
236 //we need to open a new one
237 //first close the existing one
238 if (minf->dataHandler) gf_isom_datamap_close(minf);
239
240 //if self-contained, assign the input file
241 if (SelfCont) {
242 //if no edit, open the input file
243 if (!Edit) {
244 if (mdia->mediaTrack->moov->mov->movieFileMap == NULL) return GF_ISOM_INVALID_FILE;
245 minf->dataHandler = mdia->mediaTrack->moov->mov->movieFileMap;
246 } else {
247 #ifndef GPAC_DISABLE_ISOM_WRITE
248 if (mdia->mediaTrack->moov->mov->editFileMap == NULL) return GF_ISOM_INVALID_FILE;
249 minf->dataHandler = mdia->mediaTrack->moov->mov->editFileMap;
250 #else
251 //this should never be the case in an read-only MP4 file
252 return GF_BAD_PARAM;
253 #endif
254 }
255 //else this is a URL (read mode only)
256 } else {
257 e = gf_isom_datamap_new(ent->location, mdia->mediaTrack->moov->mov->fileName ? mdia->mediaTrack->moov->mov->fileName : mdia->mediaTrack->moov->mov->finalName, GF_ISOM_DATA_MAP_READ, & mdia->information->dataHandler);
258 if (e) return (e==GF_URL_ERROR) ? GF_ISOM_UNKNOWN_DATA_REF : e;
259 }
260 //OK, set the data entry index
261 minf->dataEntryIndex = dataRefIndex;
262 return GF_OK;
263 }
264
265 //return the NB of bytes actually read (used for HTTP, ...) in case file is uncomplete
gf_isom_datamap_get_data(GF_DataMap * map,u8 * buffer,u32 bufferLength,u64 Offset)266 u32 gf_isom_datamap_get_data(GF_DataMap *map, u8 *buffer, u32 bufferLength, u64 Offset)
267 {
268 if (!map || !buffer) return 0;
269
270 switch (map->type) {
271 case GF_ISOM_DATA_FILE:
272 case GF_ISOM_DATA_MEM:
273 return gf_isom_fdm_get_data((GF_FileDataMap *)map, buffer, bufferLength, Offset);
274
275 case GF_ISOM_DATA_FILE_MAPPING:
276 return gf_isom_fmo_get_data((GF_FileMappingDataMap *)map, buffer, bufferLength, Offset);
277
278 default:
279 return 0;
280 }
281 }
282
gf_isom_datamap_flush(GF_DataMap * map)283 void gf_isom_datamap_flush(GF_DataMap *map)
284 {
285 if (!map) return;
286
287 if (map->type == GF_ISOM_DATA_FILE || map->type == GF_ISOM_DATA_MEM) {
288 GF_FileDataMap *fdm = (GF_FileDataMap *)map;
289 gf_bs_flush(fdm->bs);
290 }
291 }
292
293 #ifndef GPAC_DISABLE_ISOM_WRITE
294
295 u64 FDM_GetTotalOffset(GF_FileDataMap *ptr);
296 GF_Err FDM_AddData(GF_FileDataMap *ptr, char *data, u32 dataSize);
297
gf_isom_datamap_get_offset(GF_DataMap * map)298 u64 gf_isom_datamap_get_offset(GF_DataMap *map)
299 {
300 if (!map) return 0;
301
302 switch (map->type) {
303 case GF_ISOM_DATA_FILE:
304 return FDM_GetTotalOffset((GF_FileDataMap *)map);
305 case GF_ISOM_DATA_MEM:
306 return gf_bs_get_position(map->bs);
307 default:
308 return 0;
309 }
310 }
311
312
gf_isom_datamap_add_data(GF_DataMap * ptr,u8 * data,u32 dataSize)313 GF_Err gf_isom_datamap_add_data(GF_DataMap *ptr, u8 *data, u32 dataSize)
314 {
315 if (!ptr || !data|| !dataSize) return GF_BAD_PARAM;
316
317 switch (ptr->type) {
318 case GF_ISOM_DATA_FILE:
319 case GF_ISOM_DATA_MEM:
320 return FDM_AddData((GF_FileDataMap *)ptr, data, dataSize);
321 default:
322 return GF_NOT_SUPPORTED;
323 }
324 }
325
gf_isom_fdm_new_temp(const char * sPath)326 GF_DataMap *gf_isom_fdm_new_temp(const char *sPath)
327 {
328 GF_FileDataMap *tmp;
329 GF_SAFEALLOC(tmp, GF_FileDataMap);
330 if (!tmp) return NULL;
331
332 tmp->type = GF_ISOM_DATA_FILE;
333 tmp->mode = GF_ISOM_DATA_MAP_WRITE;
334
335 if (!sPath) {
336 tmp->stream = gf_file_temp(&tmp->temp_file);
337 } else {
338 char szPath[GF_MAX_PATH];
339 if ((sPath[strlen(sPath)-1] != '\\') && (sPath[strlen(sPath)-1] != '/')) {
340 sprintf(szPath, "%s%c%p_isotmp", sPath, GF_PATH_SEPARATOR, (void*) tmp);
341 } else {
342 sprintf(szPath, "%s%p_isotmp", sPath, (void*) tmp);
343 }
344 tmp->stream = gf_fopen(szPath, "w+b");
345 tmp->temp_file = gf_strdup(szPath);
346 }
347 if (!tmp->stream) {
348 if (tmp->temp_file) gf_free(tmp->temp_file);
349 gf_free(tmp);
350 return NULL;
351 }
352 tmp->bs = gf_bs_from_file(tmp->stream, GF_BITSTREAM_WRITE);
353 if (!tmp->bs) {
354 gf_fclose(tmp->stream);
355 gf_free(tmp);
356 return NULL;
357 }
358 return (GF_DataMap *)tmp;
359 }
360
361 #endif /*GPAC_DISABLE_ISOM_WRITE*/
362
363 #include <errno.h>
364 #include <string.h>
gf_isom_fdm_new(const char * sPath,u8 mode)365 GF_DataMap *gf_isom_fdm_new(const char *sPath, u8 mode)
366 {
367 u8 bs_mode;
368 GF_FileDataMap *tmp;
369 GF_SAFEALLOC(tmp, GF_FileDataMap);
370 if (!tmp) return NULL;
371
372 tmp->mode = mode;
373
374 if (sPath == NULL) {
375 tmp->type = GF_ISOM_DATA_MEM;
376 tmp->bs = gf_bs_new (NULL, 0, GF_BITSTREAM_WRITE);
377 if (!tmp->bs) {
378 gf_free(tmp);
379 return NULL;
380 }
381 return (GF_DataMap *)tmp;
382 }
383
384 tmp->type = GF_ISOM_DATA_FILE;
385 #ifndef GPAC_DISABLE_ISOM_WRITE
386 //open a temp file
387 if (!strcmp(sPath, "mp4_tmp_edit")) {
388 //create a temp file (that only occurs in EDIT/WRITE mode)
389 tmp->stream = gf_file_temp(&tmp->temp_file);
390 // bs_mode = GF_BITSTREAM_READ;
391 }
392 #endif
393 if (!strncmp(sPath, "gmem://", 7)) {
394 u32 size;
395 u8 *mem_address;
396 if (gf_blob_get_data(sPath, &mem_address, &size) != GF_OK)
397 return NULL;
398 tmp->bs = gf_bs_new((const char *)mem_address, size, GF_BITSTREAM_READ);
399 if (!tmp->bs) {
400 gf_free(tmp);
401 return NULL;
402 }
403 return (GF_DataMap *)tmp;
404 }
405
406 switch (mode) {
407 case GF_ISOM_DATA_MAP_READ:
408 if (!tmp->stream) tmp->stream = gf_fopen(sPath, "rb");
409 bs_mode = GF_BITSTREAM_READ;
410 break;
411 ///we open the file in READ/WRITE mode, in case
412 case GF_ISOM_DATA_MAP_WRITE:
413 if (!strcmp(sPath, "_gpac_isobmff_redirect")) {
414 tmp->stream = NULL;
415 tmp->bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
416 } else {
417 if (!strcmp(sPath, "std")) {
418 tmp->stream = stdout;
419 tmp->is_stdout = 1;
420 }
421
422 if (!tmp->stream) tmp->stream = gf_fopen(sPath, "w+b");
423 if (!tmp->stream) tmp->stream = gf_fopen(sPath, "wb");
424 }
425 bs_mode = GF_BITSTREAM_WRITE;
426 break;
427 ///we open the file in CAT mode, in case
428 case GF_ISOM_DATA_MAP_CAT:
429 if (!strcmp(sPath, "_gpac_isobmff_redirect")) {
430 tmp->stream = NULL;
431 tmp->bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
432 } else {
433 if (!strcmp(sPath, "std")) {
434 tmp->stream = stdout;
435 tmp->is_stdout = 1;
436 }
437
438 if (!tmp->stream) tmp->stream = gf_fopen(sPath, "a+b");
439 if (tmp->stream) gf_fseek(tmp->stream, 0, SEEK_END);
440 }
441 bs_mode = GF_BITSTREAM_WRITE;
442 break;
443 default:
444 gf_free(tmp);
445 return NULL;
446 }
447 if (!tmp->stream && !tmp->bs) {
448 gf_free(tmp);
449 return NULL;
450 }
451 if (!tmp->bs)
452 tmp->bs = gf_bs_from_file(tmp->stream, bs_mode);
453
454 if (!tmp->bs) {
455 gf_fclose(tmp->stream);
456 gf_free(tmp);
457 return NULL;
458 }
459 return (GF_DataMap *)tmp;
460 }
461
gf_isom_fdm_del(GF_FileDataMap * ptr)462 void gf_isom_fdm_del(GF_FileDataMap *ptr)
463 {
464 if (!ptr || (ptr->type != GF_ISOM_DATA_FILE && ptr->type != GF_ISOM_DATA_MEM)) return;
465 if (ptr->bs) gf_bs_del(ptr->bs);
466 if (ptr->stream && !ptr->is_stdout)
467 gf_fclose(ptr->stream);
468
469 #ifndef GPAC_DISABLE_ISOM_WRITE
470 if (ptr->temp_file) {
471 gf_file_delete(ptr->temp_file);
472 gf_free(ptr->temp_file);
473 }
474 #endif
475 gf_free(ptr);
476 }
477
gf_isom_fdm_get_data(GF_FileDataMap * ptr,u8 * buffer,u32 bufferLength,u64 fileOffset)478 u32 gf_isom_fdm_get_data(GF_FileDataMap *ptr, u8 *buffer, u32 bufferLength, u64 fileOffset)
479 {
480 u32 bytesRead;
481
482 //can we seek till that point ???
483 if (fileOffset > gf_bs_get_size(ptr->bs))
484 return 0;
485
486 if (gf_bs_get_position(ptr->bs) != fileOffset) {
487 //we are not at the previous location, do a seek
488 if (gf_bs_seek(ptr->bs, fileOffset) != GF_OK) return 0;
489 }
490 ptr->curPos = fileOffset;
491
492 //read our data.
493 bytesRead = gf_bs_read_data(ptr->bs, buffer, bufferLength);
494 //update our cache
495 if (bytesRead == bufferLength) {
496 ptr->curPos += bytesRead;
497 } else {
498 gf_bs_get_refreshed_size(ptr->bs);
499 gf_bs_seek(ptr->bs, fileOffset);
500 bytesRead = gf_bs_read_data(ptr->bs, buffer, bufferLength);
501 //update our cache
502 if (bytesRead == bufferLength) {
503 ptr->curPos += bytesRead;
504 } else {
505 gf_bs_seek(ptr->bs, ptr->curPos);
506 bytesRead = 0;
507 }
508 }
509 ptr->last_acces_was_read = 1;
510 return bytesRead;
511 }
512
513
514 #ifndef GPAC_DISABLE_ISOM_WRITE
515
516
FDM_GetTotalOffset(GF_FileDataMap * ptr)517 u64 FDM_GetTotalOffset(GF_FileDataMap *ptr)
518 {
519 if (!ptr) return 0;
520 //the pos is not always at the end
521 //this function is called to set up the chunks
522 //so we need the next WRITE offset
523 return gf_bs_get_size(ptr->bs);
524 }
525
FDM_AddData(GF_FileDataMap * ptr,char * data,u32 dataSize)526 GF_Err FDM_AddData(GF_FileDataMap *ptr, char *data, u32 dataSize)
527 {
528 u32 ret;
529 u64 orig;
530 if (ptr->mode == GF_ISOM_DATA_MAP_READ) return GF_BAD_PARAM;
531
532 orig = gf_bs_get_size(ptr->bs);
533
534 /*last access was read, seek to end of file*/
535 if (ptr->last_acces_was_read) {
536 gf_bs_seek(ptr->bs, orig);
537 ptr->last_acces_was_read = 0;
538 }
539 //OK, write our stuff to the datamap...
540 //we don't use bs here cause we want to know more about what has been written
541 ret = gf_bs_write_data(ptr->bs, data, dataSize);
542 if (ret != dataSize) {
543 ptr->curPos = orig;
544 gf_bs_seek(ptr->bs, orig);
545 return GF_IO_ERR;
546 }
547 ptr->curPos = gf_bs_get_position(ptr->bs);
548 #if 0
549 //flush the stream !!
550 if (ptr->stream) gf_bs_flush(ptr->bs);
551 #endif
552 return GF_OK;
553 }
554
555 #endif /*GPAC_DISABLE_ISOM_WRITE*/
556
557
558 #ifdef WIN32
559
560 #include <windows.h>
561 #include <winerror.h>
562
gf_isom_fmo_new(const char * sPath,u8 mode)563 GF_DataMap *gf_isom_fmo_new(const char *sPath, u8 mode)
564 {
565 GF_FileMappingDataMap *tmp;
566 HANDLE fileH, fileMapH;
567 #ifdef _WIN32_WCE
568 unsigned short sWPath[MAX_PATH];
569 #endif
570
571 //only in read only
572 if (mode != GF_ISOM_DATA_MAP_READ) return NULL;
573
574 GF_SAFEALLOC(tmp, GF_FileMappingDataMap);
575 if (!tmp) return NULL;
576
577 tmp->type = GF_ISOM_DATA_FILE_MAPPING;
578 tmp->mode = mode;
579 tmp->name = gf_strdup(sPath);
580
581 //
582 // Open the file
583 //
584 #ifdef _WIN32_WCE
585 //convert to WIDE
586 CE_CharToWide((char *)sPath, sWPath);
587
588 fileH = CreateFileForMapping(sWPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
589 (FILE_ATTRIBUTE_READONLY | FILE_FLAG_RANDOM_ACCESS), NULL );
590 #else
591 fileH = CreateFile(sPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
592 (FILE_ATTRIBUTE_READONLY | FILE_FLAG_RANDOM_ACCESS), NULL );
593 #endif
594
595
596 if (fileH == INVALID_HANDLE_VALUE) {
597 gf_free(tmp->name);
598 gf_free(tmp);
599 return NULL;
600 }
601
602 tmp->file_size = GetFileSize(fileH, NULL);
603 if (tmp->file_size == 0xFFFFFFFF) {
604 CloseHandle(fileH);
605 gf_free(tmp->name);
606 gf_free(tmp);
607 return NULL;
608 }
609
610 //
611 // Create the mapping
612 //
613 fileMapH = CreateFileMapping(fileH, NULL, PAGE_READONLY, 0, 0, NULL);
614 if (fileMapH == NULL) {
615 CloseHandle(fileH);
616 gf_free(tmp->name);
617 gf_free(tmp);
618 return NULL;
619 }
620
621 tmp->byte_map = MapViewOfFile(fileMapH, FILE_MAP_READ, 0, 0, 0);
622 if (tmp->byte_map == NULL) {
623 CloseHandle(fileMapH);
624 CloseHandle(fileH);
625 gf_free(tmp->name);
626 gf_free(tmp);
627 return NULL;
628 }
629
630 CloseHandle(fileH);
631 CloseHandle(fileMapH);
632
633 //finaly open our bitstream (from buffer)
634 tmp->bs = gf_bs_new(tmp->byte_map, tmp->file_size, GF_BITSTREAM_READ);
635 return (GF_DataMap *)tmp;
636 }
637
gf_isom_fmo_del(GF_FileMappingDataMap * ptr)638 void gf_isom_fmo_del(GF_FileMappingDataMap *ptr)
639 {
640 if (!ptr || (ptr->type != GF_ISOM_DATA_FILE_MAPPING)) return;
641
642 if (ptr->bs) gf_bs_del(ptr->bs);
643 if (ptr->byte_map) UnmapViewOfFile(ptr->byte_map);
644 gf_free(ptr->name);
645 gf_free(ptr);
646 }
647
648
gf_isom_fmo_get_data(GF_FileMappingDataMap * ptr,u8 * buffer,u32 bufferLength,u64 fileOffset)649 u32 gf_isom_fmo_get_data(GF_FileMappingDataMap *ptr, u8 *buffer, u32 bufferLength, u64 fileOffset)
650 {
651 //can we seek till that point ???
652 if (fileOffset > ptr->file_size) return 0;
653
654 //we do only read operations, so trivial
655 memcpy(buffer, ptr->byte_map + fileOffset, bufferLength);
656 return bufferLength;
657 }
658
659 #else
660
gf_isom_fmo_new(const char * sPath,u8 mode)661 GF_DataMap *gf_isom_fmo_new(const char *sPath, u8 mode)
662 {
663 return gf_isom_fdm_new(sPath, mode);
664 }
665
gf_isom_fmo_del(GF_FileMappingDataMap * ptr)666 void gf_isom_fmo_del(GF_FileMappingDataMap *ptr)
667 {
668 gf_isom_fdm_del((GF_FileDataMap *)ptr);
669 }
670
gf_isom_fmo_get_data(GF_FileMappingDataMap * ptr,u8 * buffer,u32 bufferLength,u64 fileOffset)671 u32 gf_isom_fmo_get_data(GF_FileMappingDataMap *ptr, u8 *buffer, u32 bufferLength, u64 fileOffset)
672 {
673 return gf_isom_fdm_get_data((GF_FileDataMap *)ptr, buffer, bufferLength, fileOffset);
674 }
675
676 #endif
677
678 #endif /*GPAC_DISABLE_ISOM*/
679