📄 stbl_read.c
字号:
GF_StscEntry *nextEnt; GF_ChunkOffsetBox *stco; GF_ChunkLargeOffsetBox *co64; u32 ghostNum = 1; if (!ent->nextChunk) { if (EntryIndex+1 == count) { //not specified in the spec, what if the last sample to chunk is no written? if (stbl->ChunkOffset->type == GF_ISOM_BOX_TYPE_STCO) { stco = (GF_ChunkOffsetBox *)stbl->ChunkOffset; ghostNum = (stco->entryCount > ent->firstChunk) ? (1 + stco->entryCount - ent->firstChunk) : 1; } else { co64 = (GF_ChunkLargeOffsetBox *)stbl->ChunkOffset; ghostNum = (co64->entryCount > ent->firstChunk) ? (1 + co64->entryCount - ent->firstChunk) : 1; } } else { //this is an unknown case due to edit mode... nextEnt = (GF_StscEntry*)gf_list_get(stbl->SampleToChunk->entryList, EntryIndex+1); ghostNum = nextEnt->firstChunk - ent->firstChunk; } } else { ghostNum = (ent->nextChunk > ent->firstChunk) ? (ent->nextChunk - ent->firstChunk) : 1; } stbl->SampleToChunk->ghostNumber = ghostNum;}//Get the offset, descIndex and chunkNumber of a sample...GF_Err stbl_GetSampleInfos(GF_SampleTableBox *stbl, u32 sampleNumber, u64 *offset, u32 *chunkNumber, u32 *descIndex, u8 *isEdited){ GF_Err e; u32 i, j, k, offsetInChunk, size, count; GF_ChunkOffsetBox *stco; GF_ChunkLargeOffsetBox *co64; GF_StscEntry *ent; (*offset) = 0; (*chunkNumber) = (*descIndex) = 0; (*isEdited) = 0; if (!stbl || !sampleNumber) return GF_BAD_PARAM; count = gf_list_count(stbl->SampleToChunk->entryList); if (count==stbl->SampleSize->sampleCount) { ent = (GF_StscEntry *)gf_list_get(stbl->SampleToChunk->entryList, sampleNumber-1); if (!ent) return GF_BAD_PARAM; (*descIndex) = ent->sampleDescriptionIndex; (*chunkNumber) = sampleNumber; (*isEdited) = ent->isEdited; if ( stbl->ChunkOffset->type == GF_ISOM_BOX_TYPE_STCO) { stco = (GF_ChunkOffsetBox *)stbl->ChunkOffset; (*offset) = (u64) stco->offsets[sampleNumber - 1]; } else { co64 = (GF_ChunkLargeOffsetBox *)stbl->ChunkOffset; (*offset) = co64->offsets[sampleNumber - 1]; } return GF_OK; } //check our cache if (stbl->SampleToChunk->firstSampleInCurrentChunk && (stbl->SampleToChunk->firstSampleInCurrentChunk < sampleNumber)) { i = stbl->SampleToChunk->currentIndex;// ent = gf_list_get(stbl->SampleToChunk->entryList, i); ent = stbl->SampleToChunk->currentEntry; GetGhostNum(ent, i, count, stbl); k = stbl->SampleToChunk->currentChunk; } else { i = 0; stbl->SampleToChunk->currentIndex = 0; stbl->SampleToChunk->currentChunk = 1; stbl->SampleToChunk->firstSampleInCurrentChunk = 1; ent = (GF_StscEntry*)gf_list_get(stbl->SampleToChunk->entryList, 0); stbl->SampleToChunk->currentEntry = ent; GetGhostNum(ent, 0, count, stbl); k = stbl->SampleToChunk->currentChunk; } //first get the chunk for (; i < count; i++) { //browse from the current chunk we're browsing from index 1 for (; k <= stbl->SampleToChunk->ghostNumber; k++) { //browse all the samples in this chunk for (j = 0; j < ent->samplesPerChunk; j++) { //ok, this is our sample if (stbl->SampleToChunk->firstSampleInCurrentChunk + j == sampleNumber ) goto sample_found; } //nope, get to next chunk stbl->SampleToChunk->firstSampleInCurrentChunk += ent->samplesPerChunk; stbl->SampleToChunk->currentChunk ++; } //not in this entry, get the next entry if not the last one if (i+1 != count) { ent = (GF_StscEntry*)gf_list_get(stbl->SampleToChunk->entryList, i+1); //update the GhostNumber GetGhostNum(ent, i+1, count, stbl); //update the entry in our cache stbl->SampleToChunk->currentEntry = ent; stbl->SampleToChunk->currentIndex = i+1; stbl->SampleToChunk->currentChunk = 1; k = 1; } } //if we get here, gasp, the sample was not found return GF_ISOM_INVALID_FILE;sample_found: (*descIndex) = ent->sampleDescriptionIndex; (*chunkNumber) = ent->firstChunk + stbl->SampleToChunk->currentChunk - 1; (*isEdited) = ent->isEdited; //ok, get the size of all the previous sample offsetInChunk = 0; //warning, firstSampleInChunk is at least 1 - not 0 for (i = stbl->SampleToChunk->firstSampleInCurrentChunk; i < sampleNumber; i++) { e = stbl_GetSampleSize(stbl->SampleSize, i, &size); if (e) return e; offsetInChunk += size; } //OK, that's the size of our offset in the chunk //now get the chunk if ( stbl->ChunkOffset->type == GF_ISOM_BOX_TYPE_STCO) { stco = (GF_ChunkOffsetBox *)stbl->ChunkOffset; if (stco->entryCount < (*chunkNumber) ) return GF_ISOM_INVALID_FILE; (*offset) = (u64) stco->offsets[(*chunkNumber) - 1] + (u64) offsetInChunk; } else { co64 = (GF_ChunkLargeOffsetBox *)stbl->ChunkOffset; if (co64->entryCount < (*chunkNumber) ) return GF_ISOM_INVALID_FILE; (*offset) = co64->offsets[(*chunkNumber) - 1] + (u64) offsetInChunk; } return GF_OK;}GF_Err stbl_GetSampleShadow(GF_ShadowSyncBox *stsh, u32 *sampleNumber, u32 *syncNum){ u32 i, count; GF_StshEntry *ent; if (stsh->r_LastFoundSample && (stsh->r_LastFoundSample <= *sampleNumber)) { i = stsh->r_LastEntryIndex; } else { i = 0; stsh->r_LastFoundSample = 1; } ent = NULL; (*syncNum) = 0; count = gf_list_count(stsh->entries); for (; i<count; i++) { ent = (GF_StshEntry*)gf_list_get(stsh->entries, i); //we get the exact desired sample ! if (ent->shadowedSampleNumber == *sampleNumber) { (*syncNum) = ent->syncSampleNumber; stsh->r_LastFoundSample = *sampleNumber; stsh->r_LastEntryIndex = i; return GF_OK; } else if (ent->shadowedSampleNumber > *sampleNumber) { //do we have an entry before ? If not, there is no shadowing available //for this sample if (!i) return GF_OK; //ok, indicate the previous ShadowedSample ent = (GF_StshEntry*)gf_list_get(stsh->entries, i-1); (*syncNum) = ent->syncSampleNumber; //change the sample number (*sampleNumber) = ent->shadowedSampleNumber; //reset the cache to the last ShadowedSample stsh->r_LastEntryIndex = i-1; stsh->r_LastFoundSample = ent->shadowedSampleNumber; } } stsh->r_LastEntryIndex = i-1; stsh->r_LastFoundSample = ent ? ent->shadowedSampleNumber : 0; return GF_OK;}GF_Err stbl_GetPaddingBits(GF_PaddingBitsBox *padb, u32 SampleNumber, u8 *PadBits){ if (!PadBits) return GF_BAD_PARAM; *PadBits = 0; if (!padb || !padb->padbits) return GF_OK; //the spec says "should" not shall. return 0 padding if (padb->SampleCount < SampleNumber) return GF_OK; *PadBits = padb->padbits[SampleNumber-1]; return GF_OK;}//Set the RAP flag of a sampleGF_Err stbl_GetSampleDepType(GF_SampleDependencyTypeBox *sdep, u32 SampleNumber, u32 *dependsOn, u32 *dependedOn, u32 *redundant){ u8 flag; assert(dependsOn && dependedOn && redundant); *dependsOn = *dependedOn = *redundant = 0; if (SampleNumber > sdep->sampleCount) return GF_BAD_PARAM; flag = sdep->sample_info[SampleNumber-1]; *dependsOn = (flag >> 4) & 3; *dependedOn = (flag >> 2) & 3; *redundant = (flag) & 3; return GF_OK;}u32 stbl_GetSampleFragmentCount(GF_SampleFragmentBox *stsf, u32 sampleNumber){ GF_StsfEntry *ent; u32 i, count; if (!stsf) return 0; //check cache if (!stsf->r_currentEntry || (stsf->r_currentEntry->SampleNumber < sampleNumber)) { stsf->r_currentEntry = NULL; stsf->r_currentEntryIndex = 0; } i = stsf->r_currentEntryIndex; count = gf_list_count(stsf->entryList); for (; i<count; i++) { ent = (GF_StsfEntry *)gf_list_get(stsf->entryList, i); if (ent->SampleNumber == sampleNumber) { stsf->r_currentEntry = ent; stsf->r_currentEntryIndex = i; return ent->fragmentCount; } } //not found return 0;}u32 stbl_GetSampleFragmentSize(GF_SampleFragmentBox *stsf, u32 sampleNumber, u32 FragmentIndex){ GF_StsfEntry *ent; u32 i, count; if (!stsf || !FragmentIndex) return 0; //check cache if (!stsf->r_currentEntry || (stsf->r_currentEntry->SampleNumber < sampleNumber)) { stsf->r_currentEntry = NULL; stsf->r_currentEntryIndex = 0; } i = stsf->r_currentEntryIndex; count = gf_list_count(stsf->entryList); for (; i<count; i++) { ent = (GF_StsfEntry *)gf_list_get(stsf->entryList, i); if (ent->SampleNumber == sampleNumber) { stsf->r_currentEntry = ent; stsf->r_currentEntryIndex = i; if (FragmentIndex > ent->fragmentCount) return 0; return ent->fragmentSizes[FragmentIndex - 1]; } } //not found return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -