예제 #1
0
GF_Err TTIn_LoadFile(GF_InputService *plug, const char *url, Bool is_cache)
{
    GF_Err e;
    GF_MediaImporter import;
    char szFILE[GF_MAX_PATH];
    TTIn *tti = (TTIn *)plug->priv;
    const char *cache_dir;
    if (!tti || !url)
        return GF_BAD_PARAM;
    cache_dir = gf_modules_get_option((GF_BaseInterface *)plug, "General", "CacheDirectory");
    if (cache_dir && strlen(cache_dir)) {
        if (cache_dir[strlen(cache_dir)-1] != GF_PATH_SEPARATOR) {
            sprintf(szFILE, "%s%csrt_%p_mp4", cache_dir, GF_PATH_SEPARATOR, tti);
        } else {
            sprintf(szFILE, "%ssrt_%p_mp4", cache_dir, tti);
        }
    } else {
        sprintf(szFILE, "%p_temp_mp4", tti);
    }
    tti->mp4 = gf_isom_open(szFILE, GF_ISOM_OPEN_WRITE, NULL);
    if (!tti->mp4) return gf_isom_last_error(NULL);
    if (tti->szFile)
        gf_free(tti->szFile);
    tti->szFile = gf_strdup(szFILE);

    memset(&import, 0, sizeof(GF_MediaImporter));
    import.dest = tti->mp4;
    /*override layout from sub file*/
    import.flags = GF_IMPORT_SKIP_TXT_BOX;
    import.in_name = gf_strdup(url);

    e = gf_media_import(&import);
    if (!e) {
        tti->tt_track = 1;
        gf_isom_text_set_streaming_mode(tti->mp4, 1);
    }
    if (import.in_name)
        gf_free(import.in_name);
    return e;
}
예제 #2
0
static GF_Err gf_sm_load_run_isom(GF_SceneLoader *load)
{
	GF_Err e;
	FILE *logs;
	u32 i, j, di, nbBifs, nbLaser, nb_samp, samp_done, init_offset;
	GF_StreamContext *sc;
	GF_ESD *esd;
	GF_ODCodec *od_dec;
#ifndef GPAC_DISABLE_BIFS
	GF_BifsDecoder *bifs_dec;
#endif
#ifndef GPAC_DISABLE_LASER
	GF_LASeRCodec *lsr_dec;
#endif

	if (!load || !load->isom) return GF_BAD_PARAM;

	nbBifs = nbLaser = 0;
	e = GF_OK;
#ifndef GPAC_DISABLE_BIFS
	bifs_dec = gf_bifs_decoder_new(load->scene_graph, 1);
	gf_bifs_decoder_set_extraction_path(bifs_dec, load->localPath, load->fileName);
#endif
	od_dec = gf_odf_codec_new();
	logs = NULL;
#ifndef GPAC_DISABLE_LASER
	lsr_dec = gf_laser_decoder_new(load->scene_graph);
#endif
	esd = NULL;
	/*load each stream*/
	nb_samp = 0;
	for (i=0; i<gf_isom_get_track_count(load->isom); i++) {
		u32 type = gf_isom_get_media_type(load->isom, i+1);
		switch (type) {
		case GF_ISOM_MEDIA_SCENE:
		case GF_ISOM_MEDIA_OD:
			nb_samp += gf_isom_get_sample_count(load->isom, i+1);
			break;
		default:
			break;
		}
	}
	samp_done = 1;
	gf_isom_text_set_streaming_mode(load->isom, 1);

	for (i=0; i<gf_isom_get_track_count(load->isom); i++) {
		u32 type = gf_isom_get_media_type(load->isom, i+1);
		switch (type) {
		case GF_ISOM_MEDIA_SCENE:
		case GF_ISOM_MEDIA_OD:
			break;
		default:
			continue;
		}
		esd = gf_isom_get_esd(load->isom, i+1, 1);
		if (!esd) continue;


		if ((esd->decoderConfig->objectTypeIndication == GPAC_OTI_SCENE_AFX) ||
		        (esd->decoderConfig->objectTypeIndication == GPAC_OTI_SCENE_SYNTHESIZED_TEXTURE)
		   ) {
			nb_samp += gf_isom_get_sample_count(load->isom, i+1);
			continue;
		}
		sc = gf_sm_stream_new(load->ctx, esd->ESID, esd->decoderConfig->streamType, esd->decoderConfig->objectTypeIndication);
		sc->streamType = esd->decoderConfig->streamType;
		sc->ESID = esd->ESID;
		sc->objectType = esd->decoderConfig->objectTypeIndication;
		sc->timeScale = gf_isom_get_media_timescale(load->isom, i+1);

		/*we still need to reconfig the BIFS*/
		if (esd->decoderConfig->streamType==GF_STREAM_SCENE) {
#ifndef GPAC_DISABLE_BIFS
			/*BIFS*/
			if (esd->decoderConfig->objectTypeIndication<=2) {
				if (!esd->dependsOnESID && nbBifs && !i)
					mp4_report(load, GF_OK, "several scene namespaces used or improper scene dependencies in file - import may be incorrect");
				if (!esd->decoderConfig->decoderSpecificInfo) {
					/* Hack for T-DMB non compliant streams */
					e = gf_bifs_decoder_configure_stream(bifs_dec, esd->ESID, NULL, 0, esd->decoderConfig->objectTypeIndication);
				} else {
					e = gf_bifs_decoder_configure_stream(bifs_dec, esd->ESID, esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, esd->decoderConfig->objectTypeIndication);
				}
				if (e) goto exit;
				nbBifs++;
			}
#endif

#ifndef GPAC_DISABLE_LASER
			/*LASER*/
			if (esd->decoderConfig->objectTypeIndication==0x09) {
				if (!esd->dependsOnESID && nbBifs && !i)
					mp4_report(load, GF_OK, "several scene namespaces used or improper scene dependencies in file - import may be incorrect");
				e = gf_laser_decoder_configure_stream(lsr_dec, esd->ESID, esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength);
				if (e) goto exit;
				nbLaser++;
			}
#endif
		}

		init_offset = 0;
		/*dump all AUs*/
		for (j=0; j<gf_isom_get_sample_count(load->isom, i+1); j++) {
			GF_AUContext *au;
			GF_ISOSample *samp = gf_isom_get_sample(load->isom, i+1, j+1, &di);
			if (!samp) {
				mp4_report(load, gf_isom_last_error(load->isom), "Unable to fetch sample %d from track ID %d - aborting track import", j+1, gf_isom_get_track_id(load->isom, i+1));
				break;
			}
			/*check if track has initial offset*/
			if (!j && gf_isom_get_edit_segment_count(load->isom, i+1)) {
				u64 EditTime, dur, mtime;
				u8 mode;
				gf_isom_get_edit_segment(load->isom, i+1, 1, &EditTime, &dur, &mtime, &mode);
				if (mode==GF_ISOM_EDIT_EMPTY) {
					init_offset = (u32) (dur * sc->timeScale / gf_isom_get_timescale(load->isom) );
				}
			}
			samp->DTS += init_offset;

			au = gf_sm_stream_au_new(sc, samp->DTS, ((Double)(s64) samp->DTS) / sc->timeScale, (samp->IsRAP==RAP) ? 1 : 0);

			if (esd->decoderConfig->streamType==GF_STREAM_SCENE) {
#ifndef GPAC_DISABLE_BIFS
				if (esd->decoderConfig->objectTypeIndication<=2)
					e = gf_bifs_decode_command_list(bifs_dec, esd->ESID, samp->data, samp->dataLength, au->commands);
#endif
#ifndef GPAC_DISABLE_LASER
				if (esd->decoderConfig->objectTypeIndication==0x09)
					e = gf_laser_decode_command_list(lsr_dec, esd->ESID, samp->data, samp->dataLength, au->commands);
#endif
			} else {
				e = gf_odf_codec_set_au(od_dec, samp->data, samp->dataLength);
				if (!e) e = gf_odf_codec_decode(od_dec);
				if (!e) {
					while (1) {
						GF_ODCom *odc = gf_odf_codec_get_com(od_dec);
						if (!odc) break;
						/*update ESDs if any*/
						UpdateODCommand(load->isom, odc);
						gf_list_add(au->commands, odc);
					}
				}
			}
			gf_isom_sample_del(&samp);
			if (e) {
				mp4_report(load, gf_isom_last_error(load->isom), "decoding sample %d from track ID %d failed", j+1, gf_isom_get_track_id(load->isom, i+1));
				goto exit;
			}

			samp_done++;
			gf_set_progress("MP4 Loading", samp_done, nb_samp);
		}
		gf_odf_desc_del((GF_Descriptor *) esd);
		esd = NULL;
	}
	gf_isom_text_set_streaming_mode(load->isom, 0);

exit:
#ifndef GPAC_DISABLE_BIFS
	gf_bifs_decoder_del(bifs_dec);
#endif
	gf_odf_codec_del(od_dec);
#ifndef GPAC_DISABLE_LASER
	gf_laser_decoder_del(lsr_dec);
#endif
	if (esd) gf_odf_desc_del((GF_Descriptor *) esd);
	if (logs) gf_fclose(logs);
	return e;
}
예제 #3
0
파일: read.c 프로젝트: supperlitt/gpac
/*fixme, this doesn't work properly with respect to @expect_type*/
static GF_Descriptor *ISOR_GetServiceDesc(GF_InputService *plug, u32 expect_type, const char *sub_url)
{
    u32 count, nb_st, i, trackID;
    GF_ESD *esd;
    ISOMReader *read;
    GF_InitialObjectDescriptor *iod;
    if (!plug || !plug->priv) return NULL;
    read = (ISOMReader *) plug->priv;
    if (!read->mov) return NULL;

    /*no matter what always read text as TTUs*/
    gf_isom_text_set_streaming_mode(read->mov, 1);

    trackID = 0;
    if (!sub_url) {
        trackID = read->base_track_id;
        read->base_track_id = 0;
    } else {
        char *ext = strrchr(sub_url, '#');
        if (!ext) {
            trackID = 0;
        } else {
            if (!strnicmp(ext, "#trackID=", 9)) trackID = atoi(ext+9);
            else if (!stricmp(ext, "#video")) trackID = get_track_id(read->mov, GF_ISOM_MEDIA_VISUAL, 0);
            else if (!strnicmp(ext, "#video", 6)) {
                trackID = atoi(ext+6);
                trackID = get_track_id(read->mov, GF_ISOM_MEDIA_VISUAL, trackID);
            }
            else if (!stricmp(ext, "#audio")) trackID = get_track_id(read->mov, GF_ISOM_MEDIA_AUDIO, 0);
            else if (!strnicmp(ext, "#audio", 6)) {
                trackID = atoi(ext+6);
                trackID = get_track_id(read->mov, GF_ISOM_MEDIA_AUDIO, trackID);
            }
            else trackID = atoi(ext+1);

            /*if trackID is 0, assume this is a fragment identifier*/
        }
    }

    if (!trackID && (expect_type!=GF_MEDIA_OBJECT_SCENE) && (expect_type!=GF_MEDIA_OBJECT_UNDEF)) {
        for (i=0; i<gf_isom_get_track_count(read->mov); i++) {
            u32 type = gf_isom_get_media_type(read->mov, i+1);
            if (
                ((type==GF_ISOM_MEDIA_VISUAL) && (expect_type==GF_MEDIA_OBJECT_VIDEO))
                || ((type==GF_ISOM_MEDIA_AUDIO) && (expect_type==GF_MEDIA_OBJECT_AUDIO)) ) {
                trackID = gf_isom_get_track_id(read->mov, i+1);
                break;
            }

        }
    }
    if (trackID && (expect_type!=GF_MEDIA_OBJECT_SCENE) ) {
        u32 track = gf_isom_get_track_by_id(read->mov, trackID);
        if (!track) return NULL;
        esd = gf_media_map_esd(read->mov, track);
        esd->OCRESID = 0;
        iod = (GF_InitialObjectDescriptor *) gf_isom_get_root_od(read->mov);
        if (!iod) {
            iod = (GF_InitialObjectDescriptor *) gf_odf_desc_new(GF_ODF_IOD_TAG);
            iod->OD_profileAndLevel = iod->audio_profileAndLevel = iod->graphics_profileAndLevel = iod->scene_profileAndLevel = iod->visual_profileAndLevel = 0xFE;
        } else {
            while (gf_list_count(iod->ESDescriptors)) {
                GF_ESD *old = (GF_ESD *)gf_list_get(iod->ESDescriptors, 0);
                gf_odf_desc_del((GF_Descriptor *) old);
                gf_list_rem(iod->ESDescriptors, 0);
            }
        }
        gf_list_add(iod->ESDescriptors, esd);
        isor_emulate_chapters(read->mov, iod);
        return (GF_Descriptor *) iod;
    }

    iod = NULL;
    if (check_mpeg4_systems(plug, read->mov)) {
        iod = (GF_InitialObjectDescriptor *) gf_isom_get_root_od(read->mov);
        if (!iod) {
#ifndef GPAC_DISABLE_LOG
            GF_Err e = gf_isom_last_error(read->mov);
            if (e) {
                GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[IsoMedia] Cannot fetch MPEG-4 IOD (error %s) - generating one\n", gf_error_to_string(e) ));
            } else {
                GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[IsoMedia] No MPEG-4 IOD found in file - generating one\n"));
            }
#endif
        }
    }
    if (!iod) return isor_emulate_iod(read);

    count = gf_list_count(iod->ESDescriptors);
    if (!count) {
        gf_odf_desc_del((GF_Descriptor*) iod);
        return isor_emulate_iod(read);
    }
    if (count==1) {
        esd = (GF_ESD *)gf_list_get(iod->ESDescriptors, 0);
        switch (esd->decoderConfig->streamType) {
        case GF_STREAM_SCENE:
        case GF_STREAM_PRIVATE_SCENE:
            break;
        case GF_STREAM_VISUAL:
            if (expect_type!=GF_MEDIA_OBJECT_VIDEO) {
                gf_odf_desc_del((GF_Descriptor*) iod);
                return isor_emulate_iod(read);
            }
            break;
        case GF_STREAM_AUDIO:
            /*we need a fake scene graph*/
            if (expect_type!=GF_MEDIA_OBJECT_AUDIO) {
                gf_odf_desc_del((GF_Descriptor*) iod);
                return isor_emulate_iod(read);
            }
            break;
        default:
            gf_odf_desc_del((GF_Descriptor*) iod);
            return NULL;
        }
    }
    /*check IOD is not badly formed (eg mixing audio, video or text streams)*/
    nb_st = 0;
    for (i=0; i<count; i++) {
        esd = (GF_ESD *)gf_list_get(iod->ESDescriptors, i);
        switch (esd->decoderConfig->streamType) {
        case GF_STREAM_VISUAL:
            nb_st |= 1;
            break;
        case GF_STREAM_AUDIO:
            nb_st |= 2;
            break;
        case GF_STREAM_TEXT:
            nb_st |= 4;
            break;
        }
    }
    if ( (nb_st & 1) + (nb_st & 2) + (nb_st & 4) > 1) {
        gf_odf_desc_del((GF_Descriptor*) iod);
        return isor_emulate_iod(read);
    }

    isor_emulate_chapters(read->mov, iod);
    return (GF_Descriptor *) iod;
}