📄 hint_track.c
字号:
samp = gf_isom_hint_sample_new(entry->type); if (!samp) return GF_NOT_SUPPORTED; //OK, let's store the time of this sample samp->TransmissionTime = TransmissionTime; //OK, set our sample in the entry... entry->hint_sample = samp; return GF_OK;}//stores the hint sample in the file//set IsRandomAccessPoint if you want to indicate that this is a random access point //in the streamGF_Err gf_isom_end_hint_sample(GF_ISOFile *the_file, u32 trackNumber, u8 IsRandomAccessPoint){ GF_TrackBox *trak; GF_HintSampleEntryBox *entry; u32 dataRefIndex; GF_Err e; GF_BitStream *bs; GF_ISOSample *samp; trak = gf_isom_get_track_from_file(the_file, trackNumber); if (!trak || !IsHintTrack(trak)) return GF_BAD_PARAM; e = Media_GetSampleDesc(trak->Media, trak->Media->information->sampleTable->currentEntryIndex, (GF_SampleEntryBox **) &entry, &dataRefIndex); if (e) return e; if (!entry->hint_sample) return GF_BAD_PARAM; //first of all, we need to adjust the offset for data referenced IN THIS hint sample //and get some PckSize e = AdjustHintInfo(entry, trak->Media->information->sampleTable->SampleSize->sampleCount + 1); if (e) return e; //ok, let's write the sample bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); e = gf_isom_hint_sample_write(entry->hint_sample, bs); if (e) { gf_bs_del(bs); return e; } samp = gf_isom_sample_new(); samp->CTS_Offset = 0; samp->IsRAP = IsRandomAccessPoint; samp->DTS = entry->hint_sample->TransmissionTime; //get the sample gf_bs_get_content(bs, &samp->data, &samp->dataLength); gf_bs_del(bs); //finally add the sample e = gf_isom_add_sample(the_file, trackNumber, trak->Media->information->sampleTable->currentEntryIndex, samp); gf_isom_sample_del(&samp); //and delete the sample in our entry ... gf_isom_hint_sample_del(entry->hint_sample); entry->hint_sample = NULL; return e;}//adds a blank chunk of data in the sample that is skipped while streamingGF_Err gf_isom_hint_blank_data(GF_ISOFile *the_file, u32 trackNumber, u8 AtBegin){ GF_TrackBox *trak; GF_HintSampleEntryBox *entry; u32 count; GF_HintPacket *pck; GF_EmptyDTE *dte; GF_Err e; trak = gf_isom_get_track_from_file(the_file, trackNumber); if (!trak || !IsHintTrack(trak)) return GF_BAD_PARAM; e = Media_GetSampleDesc(trak->Media, trak->Media->information->sampleTable->currentEntryIndex, (GF_SampleEntryBox **) &entry, &count); if (e) return e; if (!entry->hint_sample) return GF_BAD_PARAM; count = gf_list_count(entry->hint_sample->packetTable); if (!count) return GF_BAD_PARAM; pck = (GF_HintPacket *)gf_list_get(entry->hint_sample->packetTable, count - 1); dte = (GF_EmptyDTE *) NewDTE(0); return gf_isom_hint_pck_add_dte(entry->hint_sample->HintType, pck, (GF_GenericDTE *)dte, AtBegin);}//adds a chunk of data (max 14 bytes) in the packet that is directly copied //while streamingGF_Err gf_isom_hint_direct_data(GF_ISOFile *the_file, u32 trackNumber, char *data, u32 dataLength, u8 AtBegin){ GF_TrackBox *trak; GF_HintSampleEntryBox *entry; u32 count; GF_HintPacket *pck; GF_ImmediateDTE *dte; GF_Err e; u32 offset = 0; if (!dataLength) return GF_OK; trak = gf_isom_get_track_from_file(the_file, trackNumber); if (!trak || !IsHintTrack(trak) || (dataLength > 14)) return GF_BAD_PARAM; e = Media_GetSampleDesc(trak->Media, trak->Media->information->sampleTable->currentEntryIndex, (GF_SampleEntryBox **) &entry, &count); if (e) return e; if (!entry->hint_sample) return GF_BAD_PARAM; count = gf_list_count(entry->hint_sample->packetTable); if (!count) return GF_BAD_PARAM; pck = (GF_HintPacket *)gf_list_get(entry->hint_sample->packetTable, count - 1); dte = (GF_ImmediateDTE *) NewDTE(1); memcpy(dte->data, data + offset, dataLength); dte->dataLength = dataLength; return gf_isom_hint_pck_add_dte(entry->hint_sample->HintType, pck, (GF_GenericDTE *)dte, AtBegin);}GF_Err gf_isom_hint_sample_data(GF_ISOFile *the_file, u32 trackNumber, u32 SourceTrackID, u32 SampleNumber, u16 DataLength, u32 offsetInSample, char *extra_data, u8 AtBegin){ GF_TrackBox *trak; GF_HintSampleEntryBox *entry; u32 count; u16 refIndex; GF_HintPacket *pck; GF_SampleDTE *dte; GF_Err e; GF_TrackReferenceTypeBox *hint; trak = gf_isom_get_track_from_file(the_file, trackNumber); if (!trak || !IsHintTrack(trak)) return GF_BAD_PARAM; e = Media_GetSampleDesc(trak->Media, trak->Media->information->sampleTable->currentEntryIndex, (GF_SampleEntryBox **) &entry, &count); if (e) return e; if (!entry->hint_sample) return GF_BAD_PARAM; count = gf_list_count(entry->hint_sample->packetTable); if (!count) return GF_BAD_PARAM; pck = (GF_HintPacket *)gf_list_get(entry->hint_sample->packetTable, count - 1); dte = (GF_SampleDTE *) NewDTE(2); dte->dataLength = DataLength; dte->sampleNumber = SampleNumber; dte->byteOffset = offsetInSample; //we're getting data from another track if (SourceTrackID != trak->Header->trackID) { //get (or set) the track reference index e = Track_FindRef(trak, GF_ISOM_REF_HINT, &hint); if (e) return e; e = reftype_AddRefTrack(hint, SourceTrackID, &refIndex); if (e) return e; //WARNING: IN QT, MUST BE 0-based !!! dte->trackRefIndex = (u8) (refIndex - 1); } else { //we're in the hint track dte->trackRefIndex = (s8) -1; //basic check... if (SampleNumber > trak->Media->information->sampleTable->SampleSize->sampleCount + 1) { DelDTE((GF_GenericDTE *)dte); return GF_BAD_PARAM; } //are we in the current sample ?? if (!SampleNumber || (SampleNumber == trak->Media->information->sampleTable->SampleSize->sampleCount + 1)) { //we adding some stuff in the current sample ... dte->byteOffset += entry->hint_sample->dataLength; entry->hint_sample->AdditionalData = (char*)realloc(entry->hint_sample->AdditionalData, sizeof(char) * (entry->hint_sample->dataLength + DataLength)); if (AtBegin) { if (entry->hint_sample->dataLength) memmove(entry->hint_sample->AdditionalData + entry->hint_sample->dataLength, entry->hint_sample->AdditionalData, entry->hint_sample->dataLength); memcpy(entry->hint_sample->AdditionalData, extra_data, DataLength); /*offset existing DTE*/ gf_isom_hint_pck_offset(entry->hint_sample->HintType, pck, DataLength, SampleNumber); } else { memcpy(entry->hint_sample->AdditionalData + entry->hint_sample->dataLength, extra_data, DataLength); } entry->hint_sample->dataLength += DataLength; //and set the sample number ... dte->sampleNumber = trak->Media->information->sampleTable->SampleSize->sampleCount + 1; } } //OK, add the entry return gf_isom_hint_pck_add_dte(entry->hint_sample->HintType, pck, (GF_GenericDTE *)dte, AtBegin);}GF_Err gf_isom_hint_sample_description_data(GF_ISOFile *the_file, u32 trackNumber, u32 SourceTrackID, u32 StreamDescriptionIndex, u16 DataLength, u32 offsetInDescription, u8 AtBegin){ GF_TrackBox *trak; GF_HintSampleEntryBox *entry; u32 count; u16 refIndex; GF_HintPacket *pck; GF_StreamDescDTE *dte; GF_Err e; GF_TrackReferenceTypeBox *hint; trak = gf_isom_get_track_from_file(the_file, trackNumber); if (!trak || !IsHintTrack(trak)) return GF_BAD_PARAM; e = Media_GetSampleDesc(trak->Media, trak->Media->information->sampleTable->currentEntryIndex, (GF_SampleEntryBox **) &entry, &count); if (e) return e; if (!entry->hint_sample) return GF_BAD_PARAM; count = gf_list_count(entry->hint_sample->packetTable); if (!count) return GF_BAD_PARAM; pck = (GF_HintPacket *)gf_list_get(entry->hint_sample->packetTable, count - 1); dte = (GF_StreamDescDTE *) NewDTE(3); dte->byteOffset = offsetInDescription; dte->dataLength = DataLength; dte->streamDescIndex = StreamDescriptionIndex; if (SourceTrackID == trak->Header->trackID) { dte->trackRefIndex = (s8) -1; } else { //get (or set) the track reference index e = Track_FindRef(trak, GF_ISOM_REF_HINT, &hint); if (e) return e; e = reftype_AddRefTrack(hint, SourceTrackID, &refIndex); if (e) return e; //WARNING: IN QT, MUST BE 0-based !!! dte->trackRefIndex = (u8) (refIndex - 1); } return gf_isom_hint_pck_add_dte(entry->hint_sample->HintType, pck, (GF_GenericDTE *)dte, AtBegin);}#endif //GPAC_READ_ONLY#ifndef GPAC_READ_ONLYGF_Err gf_isom_rtp_packet_set_flags(GF_ISOFile *the_file, u32 trackNumber, u8 PackingBit, u8 eXtensionBit, u8 MarkerBit, u8 disposable_packet, u8 IsRepeatedPacket){ GF_TrackBox *trak; GF_HintSampleEntryBox *entry; GF_RTPPacket *pck; u32 dataRefIndex, ind; GF_Err e; trak = gf_isom_get_track_from_file(the_file, trackNumber); if (!trak || !CheckHintFormat(trak, GF_ISOM_HINT_RTP)) return GF_BAD_PARAM; e = Media_GetSampleDesc(trak->Media, trak->Media->information->sampleTable->currentEntryIndex, (GF_SampleEntryBox **) &entry, &dataRefIndex); if (e) return e; if (!entry->hint_sample) return GF_BAD_PARAM; ind = gf_list_count(entry->hint_sample->packetTable); if (!ind) return GF_BAD_PARAM; pck = (GF_RTPPacket *)gf_list_get(entry->hint_sample->packetTable, ind-1); pck->P_bit = PackingBit ? 1 : 0; pck->X_bit = eXtensionBit ? 1 : 0; pck->M_bit = MarkerBit ? 1 : 0; pck->B_bit = disposable_packet ? 1 : 0; pck->R_bit = IsRepeatedPacket ? 1 : 0; return GF_OK;}GF_Err gf_isom_rtp_packet_begin(GF_ISOFile *the_file, u32 trackNumber, s32 relativeTime, u8 PackingBit, u8 eXtensionBit, u8 MarkerBit, u8 PayloadType, u8 B_frame, u8 IsRepeatedPacket, u16 SequenceNumber){ GF_TrackBox *trak; GF_HintSampleEntryBox *entry; GF_RTPPacket *pck; u32 dataRefIndex; GF_Err e; trak = gf_isom_get_track_from_file(the_file, trackNumber); if (!trak || !CheckHintFormat(trak, GF_ISOM_HINT_RTP)) return GF_BAD_PARAM; e = Media_GetSampleDesc(trak->Media, trak->Media->information->sampleTable->currentEntryIndex, (GF_SampleEntryBox **) &entry, &dataRefIndex); if (e) return e; if (!entry->hint_sample) return GF_BAD_PARAM; pck = (GF_RTPPacket *) gf_isom_hint_pck_new(entry->hint_sample->HintType); pck->P_bit = PackingBit ? 1 : 0; pck->X_bit = eXtensionBit ? 1 : 0; pck->M_bit = MarkerBit ? 1 : 0; pck->payloadType = PayloadType; pck->SequenceNumber = SequenceNumber; pck->B_bit = B_frame ? 1 : 0; pck->R_bit = IsRepeatedPacket ? 1 : 0; pck->relativeTransTime = relativeTime; return gf_list_add(entry->hint_sample->packetTable, pck);}//set the time offset of this packet. This enables packets to be placed in the hint track //in decoding order, but have their presentation time-stamp in the transmitted //packet be in a different order. Typically used for MPEG video with B-framesGF_Err gf_isom_rtp_packet_set_offset(GF_ISOFile *the_file, u32 trackNumber, s32 timeOffset){ GF_RTPOBox *rtpo; GF_TrackBox *trak; GF_HintSampleEntryBox *entry; GF_RTPPacket *pck; u32 dataRefIndex, i; GF_Err e; trak = gf_isom_get_track_from_file(the_file, trackNumber); if (!trak || !CheckHintFormat(trak, GF_ISOM_HINT_RTP)) return GF_BAD_PARAM; e = Media_GetSampleDesc(trak->Media, trak->Media->information->sampleTable->currentEntryIndex, (GF_SampleEntryBox **) &entry, &dataRefIndex); if (e) return e; if (!entry->hint_sample) return GF_BAD_PARAM; pck = (GF_RTPPacket *)gf_list_get(entry->hint_sample->packetTable, gf_list_count(entry->hint_sample->packetTable) - 1); if (!pck) return GF_BAD_PARAM; //look in the TLV i=0; while ((rtpo = (GF_RTPOBox *)gf_list_enum(pck->TLV, &i))) { if (rtpo->type == GF_ISOM_BOX_TYPE_RTPO) { rtpo->timeOffset = timeOffset; return GF_OK; } } //not found, add it rtpo = (GF_RTPOBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_RTPO); rtpo->timeOffset = timeOffset; return gf_list_add(pck->TLV, rtpo);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -