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
GF_Err gf_isom_add_meta_item_extended(GF_ISOFile *file, Bool root_meta, u32 track_num, Bool self_reference, char *resource_path,
                                      const char *item_name, u32 item_id, const char *mime_type, const char *content_encoding,
                                      GF_ImageItemProperties *image_props,
                                      const char *URL, const char *URN,
                                      char *data, u32 data_len)
{
	GF_Err e;
	GF_ItemLocationEntry *location_entry;
	GF_ItemInfoEntryBox *infe;
	GF_MetaBox *meta;
	u32 lastItemID = 0;

	if (!self_reference && !item_name && !resource_path) return GF_BAD_PARAM;
	e = CanAccessMovie(file, GF_ISOM_OPEN_WRITE);
	if (e) return e;
	meta = gf_isom_get_meta(file, root_meta, track_num);
	if (!meta) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("Trying to add item, but missing meta box"));
		return GF_BAD_PARAM;
	}

	e = FlushCaptureMode(file);
	if (e) return e;

	/*check file exists */
	if (!URN && !URL && !self_reference && !data) {
		FILE *src = gf_fopen(resource_path, "rb");
		if (!src) return GF_URL_ERROR;
		gf_fclose(src);
	}

	if (meta->item_infos) {
		u32 i;
		u32 item_count = gf_list_count(meta->item_infos->item_infos);
		for (i = 0; i < item_count; i++) {
			GF_ItemInfoEntryBox *e= (GF_ItemInfoEntryBox *)gf_list_get(meta->item_infos->item_infos, i);
			if (e->item_ID > lastItemID) lastItemID = e->item_ID;
			if (item_id == e->item_ID) {
				GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[IsoMedia] Item with id %d already exists, ignoring\n", item_id));
				item_id = 0;
			}
		}
	}

	infe = (GF_ItemInfoEntryBox *)infe_New();
	if (item_id) {
		infe->item_ID = item_id;
	} else {
		infe->item_ID = ++lastItemID;
	}

	/*get relative name*/
	if (item_name) {
		infe->item_name = gf_strdup(item_name);
	} else if (resource_path) {
		if (strrchr(resource_path, GF_PATH_SEPARATOR)) {
			infe->item_name = gf_strdup(strrchr(resource_path, GF_PATH_SEPARATOR) + 1);
		} else {
			infe->item_name = gf_strdup(resource_path);
		}
	}

	if (mime_type) {
		infe->content_type = gf_strdup(mime_type);
	} else {
		infe->content_type = gf_strdup("application/octet-stream");
	}
	if (content_encoding) infe->content_encoding = gf_strdup(content_encoding);

	/*Creation of the ItemLocation */
	location_entry = (GF_ItemLocationEntry*)gf_malloc(sizeof(GF_ItemLocationEntry));
	if (!location_entry) {
		gf_isom_box_del((GF_Box *)infe);
		return GF_OUT_OF_MEM;
	}
	memset(location_entry, 0, sizeof(GF_ItemLocationEntry));
	location_entry->extent_entries = gf_list_new();

	/*Creates an mdat if it does not exist*/
	if (!file->mdat) {
		file->mdat = (GF_MediaDataBox *)mdat_New();
		gf_list_add(file->TopBoxes, file->mdat);
	}

	/*Creation an ItemLocation Box if it does not exist*/
	if (!meta->item_locations) meta->item_locations = (GF_ItemLocationBox *)iloc_New();
	gf_list_add(meta->item_locations->location_entries, location_entry);
	location_entry->item_ID = infe->item_ID;

	if (!meta->item_infos) meta->item_infos = (GF_ItemInfoBox *) iinf_New();
	e = gf_list_add(meta->item_infos->item_infos, infe);
	if (e) return e;

	if (image_props) {
		meta_process_image_properties(meta, infe->item_ID, image_props);
	}

	/*0: the current file*/
	location_entry->data_reference_index = 0;
	if (self_reference) {
		GF_ItemExtentEntry *entry;
		GF_SAFEALLOC(entry, GF_ItemExtentEntry);
		gf_list_add(location_entry->extent_entries, entry);
		if (!infe->item_name) infe->item_name = gf_strdup("");
		return GF_OK;
	}

	/*file not copied, just referenced*/
	if (URL || URN) {
		u32 dataRefIndex;
		if (!meta->file_locations) meta->file_locations = (GF_DataInformationBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_DINF);
		if (!meta->file_locations->dref) meta->file_locations->dref = (GF_DataReferenceBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_DREF);
		e = Media_FindDataRef(meta->file_locations->dref, (char *) URL, (char *) URN, &dataRefIndex);
		if (e) return e;
		if (!dataRefIndex) {
			e = Media_CreateDataRef(meta->file_locations->dref, (char *) URL, (char *) URN, &dataRefIndex);
			if (e) return e;
		}
		location_entry->data_reference_index = dataRefIndex;
	}

	/*capture mode, write to disk*/
	if ((file->openMode == GF_ISOM_OPEN_WRITE) && !location_entry->data_reference_index) {
		FILE *src;
		GF_ItemExtentEntry *entry;
		GF_SAFEALLOC(entry, GF_ItemExtentEntry);

		location_entry->base_offset = gf_bs_get_position(file->editFileMap->bs);

		/*update base offset size*/
		if (location_entry->base_offset>0xFFFFFFFF) meta->item_locations->base_offset_size = 8;
		else if (location_entry->base_offset && !meta->item_locations->base_offset_size) meta->item_locations->base_offset_size = 4;

		entry->extent_length = 0;
		entry->extent_offset = 0;
		gf_list_add(location_entry->extent_entries, entry);

		if (data) {
			gf_bs_write_data(file->editFileMap->bs, data, data_len);
			/*update length size*/
			if (entry->extent_length>0xFFFFFFFF) meta->item_locations->length_size = 8;
			else if (entry->extent_length && !meta->item_locations->length_size) meta->item_locations->length_size = 4;
		} else if (resource_path) {
			src = gf_fopen(resource_path, "rb");
			if (src) {
				char cache_data[4096];
				u64 remain;
				gf_fseek(src, 0, SEEK_END);
				entry->extent_length = gf_ftell(src);
				gf_fseek(src, 0, SEEK_SET);

				remain = entry->extent_length;
				while (remain) {
					u32 size_cache = (remain>4096) ? 4096 : (u32) remain;
					size_t read = fread(cache_data, 1, size_cache, src);
					if (read==(size_t)-1) break;
					gf_bs_write_data(file->editFileMap->bs, cache_data, (u32) read);
					remain -= (u32) read;
				}
				gf_fclose(src);

				/*update length size*/
				if (entry->extent_length>0xFFFFFFFF) meta->item_locations->length_size = 8;
				else if (entry->extent_length && !meta->item_locations->length_size) meta->item_locations->length_size = 4;
			}
		}
	}
	/*store full path for info*/
	else if (!location_entry->data_reference_index) {
		if (data) {
			infe->full_path = (char *)gf_malloc(sizeof(char) * data_len);
			memcpy(infe->full_path, data, sizeof(char) * data_len);
			infe->data_len = data_len;
		} else {
			infe->full_path = gf_strdup(resource_path);
			infe->data_len = 0;
		}
	}
	return GF_OK;
}