示例#1
0
M4Err Media_GetSampleDescIndex(MediaAtom *mdia, u64 DTS, u32 *sampleDescIndex)
{
	M4Err e;
	u32 sampleNumber, prevSampleNumber, num;
	u64 offset;
	u8 isEdited;
	if (sampleDescIndex == NULL) return M4BadParam;

	//find the sample for this time
	e = findEntryForTime(mdia->information->sampleTable, (u32) DTS, 0, &sampleNumber, &prevSampleNumber);
	if (e) return e;

	if (!sampleNumber && !prevSampleNumber) {
		//we have to assume the track was created to be used... If we have a sampleDesc, OK
		if (ChainGetCount(mdia->information->sampleTable->SampleDescription->atomList)) {
			(*sampleDescIndex) = 1;
			return M4OK;
		}		
		return M4BadParam;
	}
	return stbl_GetSampleInfos(mdia->information->sampleTable, ( sampleNumber ? sampleNumber : prevSampleNumber), &offset, &num, sampleDescIndex, &isEdited);
}
示例#2
0
GF_Err Media_GetSampleDescIndex(GF_MediaBox *mdia, u64 DTS, u32 *sampleDescIndex)
{
	GF_Err e;
	u32 sampleNumber, prevSampleNumber, num;
	u64 offset;
	u8 isEdited;
	if (sampleDescIndex == NULL) return GF_BAD_PARAM;

	//find the sample for this time
	e = findEntryForTime(mdia->information->sampleTable, (u32) DTS, 0, &sampleNumber, &prevSampleNumber);
	if (e) return e;

	if (!sampleNumber && !prevSampleNumber) {
		//we have to assume the track was created to be used... If we have a sampleDesc, OK
		if (gf_list_count(mdia->information->sampleTable->SampleDescription->other_boxes)) {
			(*sampleDescIndex) = 1;
			return GF_OK;
		}		
		return GF_BAD_PARAM;
	}
	return stbl_GetSampleInfos(mdia->information->sampleTable, ( sampleNumber ? sampleNumber : prevSampleNumber), &offset, &num, sampleDescIndex, &isEdited);
}
示例#3
0
//WARNING: MOVIETIME IS EXPRESSED IN MEDIA TS
GF_Err GetMediaTime(GF_TrackBox *trak, Bool force_non_empty, u64 movieTime, u64 *MediaTime, s64 *SegmentStartTime, s64 *MediaOffset, u8 *useEdit, u64 *next_edit_start_plus_one)
{
#if 0
    GF_Err e;
    u32 sampleNumber, prevSampleNumber;
    u64 firstDTS;
#endif
    u32 i, count;
    Bool last_is_empty = 0;
    u64 time, lastSampleTime;
    s64 mtime;
    GF_EdtsEntry *ent;
    Double scale_ts;
    GF_SampleTableBox *stbl = trak->Media->information->sampleTable;

    if (next_edit_start_plus_one) *next_edit_start_plus_one = 0;
    *useEdit = 1;
    *MediaTime = 0;
    //no segment yet...
    *SegmentStartTime = -1;
    *MediaOffset = -1;
    if (!trak->moov->mvhd->timeScale || !trak->Media->mediaHeader->timeScale || !stbl->SampleSize) {
        return GF_ISOM_INVALID_FILE;
    }

    //no samples...
    if (!stbl->SampleSize->sampleCount) {
        lastSampleTime = 0;
    } else {
        lastSampleTime = trak->Media->mediaHeader->duration;
    }

    //No edits, 1 to 1 mapping
    if (! trak->editBox || !trak->editBox->editList) {
        *MediaTime = movieTime;
        //check this is in our media time line
        if ((*MediaTime > lastSampleTime)
#ifndef GPAC_DISABLE_ISOM_FRAGMENTS
                && !trak->moov->mov->moof
#endif
           ) {
            *MediaTime = lastSampleTime;
        }
        *useEdit = 0;
        return GF_OK;
    }
    //browse the edit list and get the time
    scale_ts = trak->Media->mediaHeader->timeScale;
    scale_ts /= trak->moov->mvhd->timeScale;

    time = 0;
    ent = NULL;
    count=gf_list_count(trak->editBox->editList->entryList);
    for (i=0; i<count; i++) {
        ent = (GF_EdtsEntry *)gf_list_get(trak->editBox->editList->entryList, i);
        if ( (time + ent->segmentDuration) * scale_ts > movieTime) {
            if (!force_non_empty || (ent->mediaTime >= 0)) {
                if (next_edit_start_plus_one) *next_edit_start_plus_one = 1 + (u64) ((time + ent->segmentDuration) * scale_ts);
                goto ent_found;
            }
        }
        time += ent->segmentDuration;
        last_is_empty = ent->segmentDuration ? 0 : 1;
    }

    if (last_is_empty) {
        ent = (GF_EdtsEntry *)gf_list_last(trak->editBox->editList->entryList);
        if (ent->mediaRate==1) {
            *MediaTime = movieTime + ent->mediaTime;
        } else {
            ent = (GF_EdtsEntry *)gf_list_get(trak->editBox->editList->entryList, 0);
            if (ent->mediaRate==-1) {
                u64 dur = (u64) (ent->segmentDuration * scale_ts);
                *MediaTime = (movieTime > dur) ? (movieTime-dur) : 0;
            }
        }
        *useEdit = 0;
        return GF_OK;
    }


    //we had nothing in the list (strange file but compliant...)
    //return the 1 to 1 mapped vale of the last media sample
    if (!ent) {
        *MediaTime = movieTime;
        //check this is in our media time line
        if (*MediaTime > lastSampleTime) *MediaTime = lastSampleTime;
        *useEdit = 0;
        return GF_OK;
    }
    //request for a bigger time that what we can give: return the last sample (undefined behavior...)
    *MediaTime = lastSampleTime;
    return GF_OK;

ent_found:
    //OK, we found our entry, set the SegmentTime
    *SegmentStartTime = time;

    //we request an empty list, there's no media here...
    if (ent->mediaTime < 0) {
        *MediaTime = 0;
        return GF_OK;
    }
    //we request a dwell edit
    if (! ent->mediaRate) {
        *MediaTime = ent->mediaTime;
        //no media offset
        *MediaOffset = 0;
        *useEdit = 2;
        return GF_OK;
    }

    /*WARNING: this can be "-1" when doing searchForward mode (to prevent jumping to next entry)*/
    mtime = ent->mediaTime + movieTime - (time * trak->Media->mediaHeader->timeScale / trak->moov->mvhd->timeScale);
    if (mtime<0) mtime = 0;
    *MediaTime = (u64) mtime;
    *MediaOffset = ent->mediaTime;

#if 0
    //
    //Sanity check: is the requested time valid ? This is to cope with wrong EditLists
    //we have the translated time, but we need to make sure we have a sample at this time ...
    //we have to find a COMPOSITION time
    e = findEntryForTime(stbl, (u32) *MediaTime, 1, &sampleNumber, &prevSampleNumber);
    if (e) return e;

    //first case: our time is after the last sample DTS (it's a broken editList somehow)
    //set the media time to the last sample
    if (!sampleNumber && !prevSampleNumber) {
        *MediaTime = lastSampleTime;
        return GF_OK;
    }
    //get the appropriated sample
    if (!sampleNumber) sampleNumber = prevSampleNumber;

    stbl_GetSampleDTS(stbl->TimeToSample, sampleNumber, &DTS);
    CTS = 0;
    if (stbl->CompositionOffset) stbl_GetSampleCTS(stbl->CompositionOffset, sampleNumber, &CTS);

    //now get the entry sample (the entry time gives the CTS, and we need the DTS
    e = findEntryForTime(stbl, (u32) ent->mediaTime, 0, &sampleNumber, &prevSampleNumber);
    if (e) return e;

    //oops, the mediaTime indicates a sample that is not in our media !
    if (!sampleNumber && !prevSampleNumber) {
        *MediaTime = lastSampleTime;
        return GF_ISOM_INVALID_FILE;
    }
    if (!sampleNumber) sampleNumber = prevSampleNumber;

    stbl_GetSampleDTS(stbl->TimeToSample, sampleNumber, &firstDTS);

    //and store the "time offset" of the desired sample in this segment
    //this is weird, used to rebuild the timeStamp when reading from the track, not the
    //media ...
    *MediaOffset = firstDTS;
#endif
    return GF_OK;
}