Пример #1
0
M4Err M4SM_LoaderRun_MP4(M4ContextLoader *load)
{
    u32 i, j, di, nbBifs, nb_samp, samp_done;
    M4StreamContext *sc, *base_bifs;
    ESDescriptor *esd;
    LPODCODEC oddec;
    LPBIFSDEC bdec;
    M4Err e;

    if (!load || !load->isom) return M4BadParam;
    base_bifs = ChainGetEntry(load->ctx->streams, 0);
    /*no scene info*/
    if (!base_bifs) return M4OK;
    nbBifs = 1;
    e = M4OK;
    bdec = BIFS_NewDecoder(load->scene_graph, 1);
    oddec = OD_NewCodec(OD_READ);
    esd = NULL;
    /*load each stream*/
    nb_samp = 0;
    for (i=0; i<M4_GetTrackCount(load->isom); i++) {
        u32 type = M4_GetMediaType(load->isom, i+1);
        switch (type) {
        case M4_BIFSMediaType:
        case M4_ODMediaType:
            nb_samp += M4_GetSampleCount(load->isom, i+1);
            break;
        default:
            break;
        }
    }
    samp_done = 1;

    for (i=0; i<M4_GetTrackCount(load->isom); i++) {
        u32 type = M4_GetMediaType(load->isom, i+1);
        switch (type) {
        case M4_BIFSMediaType:
            break;
        case M4_ODMediaType:
            break;
        default:
            continue;
        }
        esd = M4_GetStreamDescriptor(load->isom, i+1, 1);
        if (!esd) continue;

        if (base_bifs->ESID!=esd->ESID) {
            sc = M4SM_NewStream(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 = M4_GetMediaTimeScale(load->isom, i+1);
            j=0;
        } else {
            j=1;
            sc = base_bifs;
        }
        /*we still need to reconfig the BIFS*/
        if (esd->decoderConfig->streamType==M4ST_SCENE) {
            if (!esd->dependsOnESID && nbBifs && !j)
                mp4_report(load, M4OK, "Warning: several BIFS namespaces used or improper BIFS dependencies in file - import may be incorrect");
            e = BIFS_ConfigureStream(bdec, esd->ESID, esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, esd->decoderConfig->objectTypeIndication);
            if (e) goto exit;
            nbBifs++;
        }

        /*dump all AUs*/
        for (; j<M4_GetSampleCount(load->isom, i+1); j++) {
            M4AUContext *au;
            M4Sample *samp = M4_GetSample(load->isom, i+1, j+1, &di);
            if (!samp) {
                mp4_report(load, M4_GetLastError(load->isom), "Unable to fetch sample %d from track ID %d - aborting track import", j+1, M4_GetTrackID(load->isom, i+1));
                break;
//				e = M4_GetLastError(load->isom);
//				goto exit;
            }
            au = M4SM_NewAU(sc, samp->DTS, ((Double)samp->DTS) / sc->timeScale, samp->IsRAP);

            if (esd->decoderConfig->streamType==M4ST_SCENE) {
                e = BIFS_DecodeAUMemory(bdec, esd->ESID, samp->data, samp->dataLength, au->commands);
            } else {
                e = OD_SetBuffer(oddec, samp->data, samp->dataLength);
                if (!e) e = OD_DecodeAU(oddec);
                if (!e) {
                    while (1) {
                        ODCommand *odc = OD_GetCommand(oddec);
                        if (!odc) break;
                        /*update ESDs if any*/
                        UpdateODCommand(load->isom, odc);
                        ChainAddEntry(au->commands, odc);
                    }
                }
            }
            M4_DeleteSample(&samp);
            if (e) goto exit;

            samp_done++;
            if (load->OnProgress) load->OnProgress(load->cbk, samp_done, nb_samp);
        }
        OD_DeleteDescriptor((Descriptor **) &esd);
    }

exit:
    BIFS_DeleteDecoder(bdec);
    OD_DeleteCodec(oddec);
    if (esd) OD_DeleteDescriptor((Descriptor **) &esd);
    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;
}