void gf_isom_hint_pck_del(u8 HintType, GF_HintPacket *ptr) { switch (HintType) { case GF_ISMO_HINT_RTP: gf_isom_hint_rtp_del((GF_RTPPacket *)ptr); break; default: break; } }
void gf_isom_hint_pck_del(GF_HintPacket *ptr) { if (!ptr) return; switch (ptr->hint_subtype) { case GF_ISOM_BOX_TYPE_RTP_STSD: case GF_ISOM_BOX_TYPE_SRTP_STSD: case GF_ISOM_BOX_TYPE_RRTP_STSD: gf_isom_hint_rtp_del((GF_RTPPacket *)ptr); break; case GF_ISOM_BOX_TYPE_RTCP_STSD: gf_isom_hint_rtcp_del((GF_RTCPPacket *)ptr); break; default: break; } }
GF_EXPORT GF_Err gf_isom_next_hint_packet(GF_ISOFile *the_file, u32 trackNumber, char **pck_data, u32 *pck_size, Bool *disposable, Bool *repeated, u32 *trans_ts, u32 *sample_num) { GF_RTPPacket *pck; GF_Err e; GF_BitStream *bs; GF_TrackBox *trak, *ref_trak; GF_HintSampleEntryBox *entry; u32 i, count, ts; s32 cts_off; *pck_data = NULL; *pck_size = 0; if (trans_ts) *trans_ts = 0; if (disposable) *disposable = 0; if (repeated) *repeated = 0; if (sample_num) *sample_num = 0; trak = gf_isom_get_track_from_file(the_file, trackNumber); if (!trak) return GF_BAD_PARAM; e = Media_GetSampleDesc(trak->Media, 1, (GF_SampleEntryBox **) &entry, NULL); if (e) return e; switch (entry->type) { case GF_ISOM_BOX_TYPE_RTP_STSD: case GF_ISOM_BOX_TYPE_SRTP_STSD: case GF_ISOM_BOX_TYPE_RRTP_STSD: break; default: return GF_NOT_SUPPORTED; } if (!entry->hint_sample) { e = gf_isom_load_next_hint_sample(the_file, trackNumber, trak, entry); if (e) return e; } pck = (GF_RTPPacket *)gf_list_get(entry->hint_sample->packetTable, 0); gf_list_rem(entry->hint_sample->packetTable, 0); if (!pck) return GF_BAD_PARAM; bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); /*write RTP header*/ gf_bs_write_int(bs, 2, 2); /*version*/ gf_bs_write_int(bs, pck->P_bit, 1); /*P bit*/ gf_bs_write_int(bs, pck->X_bit, 1); /*X bit*/ gf_bs_write_int(bs, 0, 4); /*CSRC count*/ gf_bs_write_int(bs, pck->M_bit, 1); /*M bit*/ gf_bs_write_int(bs, pck->payloadType, 7); /*payt*/ gf_bs_write_u16(bs, entry->pck_sn); /*seq num*/ entry->pck_sn++; /*look for CTS offset in TLV*/ cts_off = 0; count = gf_list_count(pck->TLV); for (i=0; i<count; i++) { GF_RTPOBox *rtpo = (GF_RTPOBox *)gf_list_get(pck->TLV, i); if (rtpo->type == GF_ISOM_BOX_TYPE_RTPO) { cts_off = rtpo->timeOffset; break; } } /*TS - TODO check TS wrapping*/ ts = (u32) (entry->hint_sample->TransmissionTime + pck->relativeTransTime + entry->ts_offset + cts_off); gf_bs_write_u32(bs, ts ); gf_bs_write_u32(bs, entry->ssrc); /*SSRC*/ /*then build all data*/ count = gf_list_count(pck->DataTable); for (i=0; i<count; i++) { GF_GenericDTE *dte = (GF_GenericDTE *)gf_list_get(pck->DataTable, i); switch (dte->source) { /*empty*/ case 0: break; /*immediate data*/ case 1: gf_bs_write_data(bs, ((GF_ImmediateDTE *)dte)->data, ((GF_ImmediateDTE *)dte)->dataLength); break; /*sample data*/ case 2: { GF_ISOSample *samp; GF_SampleDTE *sdte = (GF_SampleDTE *)dte; /*get track if not this one*/ if (sdte->trackRefIndex != (s8) -1) { if (!entry->hint_ref || !entry->hint_ref->trackIDs) { gf_isom_hint_rtp_del(pck); gf_bs_del(bs); return GF_ISOM_INVALID_FILE; } ref_trak = gf_isom_get_track_from_id(trak->moov, entry->hint_ref->trackIDs[(u32)sdte->trackRefIndex]); } else { ref_trak = trak; } samp = gf_isom_get_data_sample(entry->hint_sample, ref_trak, sdte->sampleNumber); if (!samp) { gf_isom_hint_rtp_del(pck); gf_bs_del(bs); return GF_IO_ERR; } gf_bs_write_data(bs, samp->data + sdte->byteOffset, sdte->dataLength); } break; /*sample desc data - currently NOT SUPPORTED !!!*/ case 3: break; } } if (trans_ts) *trans_ts = ts; if (disposable) *disposable = pck->B_bit; if (repeated) *repeated = pck->R_bit; if (sample_num) *sample_num = entry->cur_sample-1; gf_bs_get_content(bs, pck_data, pck_size); gf_bs_del(bs); gf_isom_hint_rtp_del(pck); if (!gf_list_count(entry->hint_sample->packetTable)) { gf_isom_hint_sample_del(entry->hint_sample); entry->hint_sample = NULL; } return GF_OK; }