Exemple #1
0
//Create the movie for WRITE only
GF_ISOFile *gf_isom_create_movie(const char *fileName, u32 OpenMode, const char *tmp_dir)
{
    GF_Err e;

    GF_ISOFile *mov = gf_isom_new_movie();
    if (!mov) return NULL;
    mov->openMode = OpenMode;
    //then set up our movie

    //in WRITE, the input dataMap is ALWAYS NULL
    mov->movieFileMap = NULL;

    //but we have the edit one
    if (OpenMode == GF_ISOM_OPEN_WRITE) {
        //THIS IS NOT A TEMP FILE, WRITE mode is used for "live capture"
        //this file will be the final file...
        mov->fileName = gf_strdup(fileName);
        e = gf_isom_datamap_new(fileName, NULL, GF_ISOM_DATA_MAP_WRITE, & mov->editFileMap);
        if (e) goto err_exit;

        /*brand is set to ISOM by default - it may be touched until sample data is added to track*/
        gf_isom_set_brand_info( (GF_ISOFile *) mov, GF_ISOM_BRAND_ISOM, 1);
    } else {
        //we are in EDIT mode but we are creating the file -> temp file
        mov->finalName = (char*)gf_malloc(strlen(fileName) + 1);
        strcpy(mov->finalName, fileName);
        e = gf_isom_datamap_new("mp4_tmp_edit", tmp_dir, GF_ISOM_DATA_MAP_WRITE, & mov->editFileMap);
        if (e) {
            gf_isom_set_last_error(NULL, e);
            gf_isom_delete_movie(mov);
            return NULL;
        }
        //brand is set to ISOM by default
        gf_isom_set_brand_info( (GF_ISOFile *) mov, GF_ISOM_BRAND_ISOM, 1);
    }

    //create an MDAT
    mov->mdat = (GF_MediaDataBox *) mdat_New();
    gf_list_add(mov->TopBoxes, mov->mdat);

    //default behaviour is capture mode, no interleaving (eg, no rewrite of mdat)
    mov->storageMode = GF_ISOM_STORE_FLAT;
    return mov;

err_exit:
    gf_isom_set_last_error(NULL, e);
    if (mov) gf_isom_delete_movie(mov);
    return NULL;
}
Exemple #2
0
//Open a data entry of a track
//Edit is used to switch between original and edition file
GF_Err gf_isom_datamap_open(GF_MediaBox *mdia, u32 dataRefIndex, u8 Edit)
{
	GF_DataEntryBox *ent;
	GF_MediaInformationBox *minf;
	u32 SelfCont;
	GF_Err e = GF_OK;
	if ((mdia == NULL) || (! mdia->information) || !dataRefIndex)
		return GF_ISOM_INVALID_MEDIA;

	minf = mdia->information;

	if (dataRefIndex > gf_list_count(minf->dataInformation->dref->boxList))
		return GF_BAD_PARAM;

	ent = (GF_DataEntryBox*)gf_list_get(minf->dataInformation->dref->boxList, dataRefIndex - 1);
	if (ent == NULL) return GF_ISOM_INVALID_MEDIA;

	//if the current dataEntry is the desired one, and not self contained, return
	if ((minf->dataEntryIndex == dataRefIndex) && (ent->flags != 1)) {
		return GF_OK;
	}

	//we need to open a new one
	//first close the existing one
	if (minf->dataHandler) gf_isom_datamap_close(minf);

	SelfCont = 0;
	switch (ent->type) {
	case GF_ISOM_BOX_TYPE_URL:
	case GF_ISOM_BOX_TYPE_URN:
		if (ent->flags == 1) SelfCont = 1;
		break;
	default:
		SelfCont = 1;
		break;
	}
	//if self-contained, assign the input file
	if (SelfCont) {
		//if no edit, open the input file
		if (!Edit) {
			if (mdia->mediaTrack->moov->mov->movieFileMap == NULL) return GF_ISOM_INVALID_FILE;
			minf->dataHandler = mdia->mediaTrack->moov->mov->movieFileMap;
		} else {
#ifndef GPAC_DISABLE_ISOM_WRITE
			if (mdia->mediaTrack->moov->mov->editFileMap == NULL) return GF_ISOM_INVALID_FILE;
			minf->dataHandler = mdia->mediaTrack->moov->mov->editFileMap;
#else
			//this should never be the case in an read-only MP4 file
			return GF_BAD_PARAM;
#endif		
		}
	//else this is a URL (read mode only)
	} else {
		e = gf_isom_datamap_new(ent->location, mdia->mediaTrack->moov->mov->fileName, GF_ISOM_DATA_MAP_READ, & mdia->information->dataHandler);
		if (e) return (e==GF_URL_ERROR) ? GF_ISOM_UNKNOWN_DATA_REF : e;
	}
	//OK, set the data entry index
	minf->dataEntryIndex = dataRefIndex;
	return GF_OK;
}
Exemple #3
0
GF_Err Media_CheckDataEntry(GF_MediaBox *mdia, u32 dataEntryIndex)
{

	GF_DataEntryURLBox *entry;
	GF_DataMap *map;
	GF_Err e;
	if (!mdia || !dataEntryIndex || dataEntryIndex > gf_list_count(mdia->information->dataInformation->dref->other_boxes)) return GF_BAD_PARAM;

	entry = (GF_DataEntryURLBox*)gf_list_get(mdia->information->dataInformation->dref->other_boxes, dataEntryIndex - 1);
	if (!entry) return GF_ISOM_INVALID_FILE;
	if (entry->flags == 1) return GF_OK;
	
	//ok, not self contained, let's go for it...
	//we don't know what's a URN yet
	if (entry->type == GF_ISOM_BOX_TYPE_URN) return GF_NOT_SUPPORTED;
	if (mdia->mediaTrack->moov->mov->openMode == GF_ISOM_OPEN_WRITE) {
		e = gf_isom_datamap_new(entry->location, NULL, GF_ISOM_DATA_MAP_READ, &map);
	} else {
		e = gf_isom_datamap_new(entry->location, mdia->mediaTrack->moov->mov->fileName, GF_ISOM_DATA_MAP_READ, &map);
	}
	if (e) return e;
	gf_isom_datamap_del(map);
	return GF_OK;
}
Exemple #4
0
//Create and parse the movie for READ - EDIT only
GF_ISOFile *gf_isom_open_file(const char *fileName, u32 OpenMode, const char *tmp_dir)
{
    GF_Err e;
    u64 bytes;
    GF_ISOFile *mov = gf_isom_new_movie();
    if (! mov) return NULL;

    mov->fileName = gf_strdup(fileName);
    mov->openMode = OpenMode;

    if ( (OpenMode == GF_ISOM_OPEN_READ) || (OpenMode == GF_ISOM_OPEN_READ_DUMP) ) {
        //always in read ...
        mov->openMode = GF_ISOM_OPEN_READ;
        mov->es_id_default_sync = -1;
        //for open, we do it the regular way and let the GF_DataMap assign the appropriate struct
        //this can be FILE (the only one supported...) as well as remote
        //(HTTP, ...),not suported yet
        //the bitstream IS PART OF the GF_DataMap
        //as this is read-only, use a FileMapping. this is the only place where
        //we use file mapping
        e = gf_isom_datamap_new(fileName, NULL, GF_ISOM_DATA_MAP_READ_ONLY, &mov->movieFileMap);
        if (e) {
            gf_isom_set_last_error(NULL, e);
            gf_isom_delete_movie(mov);
            return NULL;
        }

#ifndef	GPAC_DISABLE_ISOM_FRAGMENTS
        if (OpenMode == GF_ISOM_OPEN_READ_DUMP) mov->FragmentsFlags |= GF_ISOM_FRAG_READ_DEBUG;
#endif

    } else {

#ifdef GPAC_DISABLE_ISOM_WRITE
        //not allowed for READ_ONLY lib
        gf_isom_delete_movie(mov);
        gf_isom_set_last_error(NULL, GF_ISOM_INVALID_MODE);
        return NULL;

#else

        //set a default output name for edited file
        mov->finalName = (char*)gf_malloc(strlen(fileName) + 5);
        if (!mov->finalName) {
            gf_isom_set_last_error(NULL, GF_OUT_OF_MEM);
            gf_isom_delete_movie(mov);
            return NULL;
        }
        strcpy(mov->finalName, "out_");
        strcat(mov->finalName, fileName);

        //open the original file with edit tag
        e = gf_isom_datamap_new(fileName, NULL, GF_ISOM_DATA_MAP_EDIT, &mov->movieFileMap);
        //if the file doesn't exist, we assume it's wanted and create one from scratch
        if (e) {
            gf_isom_set_last_error(NULL, e);
            gf_isom_delete_movie(mov);
            return NULL;
        }
        //and create a temp fileName for the edit
        e = gf_isom_datamap_new("mp4_tmp_edit", tmp_dir, GF_ISOM_DATA_MAP_WRITE, & mov->editFileMap);
        if (e) {
            gf_isom_set_last_error(NULL, e);
            gf_isom_delete_movie(mov);
            return NULL;
        }

        mov->es_id_default_sync = -1;

#endif
    }

    //OK, let's parse the movie...
    mov->LastError = gf_isom_parse_movie_boxes(mov, &bytes, 0);
    if (mov->LastError) {
        gf_isom_set_last_error(NULL, mov->LastError);
        gf_isom_delete_movie(mov);
        return NULL;
    }

    if (OpenMode == GF_ISOM_OPEN_CAT_FRAGMENTS) {
        gf_isom_datamap_del(mov->movieFileMap);
        /*reopen the movie file map in cat mode*/
        e = gf_isom_datamap_new(fileName, tmp_dir, GF_ISOM_DATA_MAP_CAT, & mov->movieFileMap);
    }
    return mov;
}