//add an SDP line to the SDP container at the movie level (presentation SDP info) //NOTE: the \r\n end of line for SDP is automatically inserted GF_EXPORT GF_Err gf_isom_sdp_add_line(GF_ISOFile *movie, const char *text) { GF_UserDataMap *map; GF_RTPBox *rtp; GF_Err e; GF_HintTrackInfoBox *hnti; char *buf; if (!movie->moov) return GF_BAD_PARAM; //check if we have a udta ... if (!movie->moov->udta) { e = moov_AddBox((GF_Box*)movie->moov, gf_isom_box_new(GF_ISOM_BOX_TYPE_UDTA)); if (e) return e; } //find a hnti in the udta map = udta_getEntry(movie->moov->udta, GF_ISOM_BOX_TYPE_HNTI, NULL); if (!map) { e = udta_AddBox(movie->moov->udta, gf_isom_box_new(GF_ISOM_BOX_TYPE_HNTI)); if (e) return e; map = udta_getEntry(movie->moov->udta, GF_ISOM_BOX_TYPE_HNTI, NULL); } //there should be one and only one hnti if (!gf_list_count(map->other_boxes) ) { e = udta_AddBox(movie->moov->udta, gf_isom_box_new(GF_ISOM_BOX_TYPE_HNTI)); if (e) return e; } else if (gf_list_count(map->other_boxes) < 1) return GF_ISOM_INVALID_FILE; hnti = (GF_HintTrackInfoBox *)gf_list_get(map->other_boxes, 0); if (!hnti->SDP) { //we have to create it by hand, as we have a duplication of box type //(GF_RTPSampleEntryBox and GF_RTPBox have the same type...) rtp = (GF_RTPBox *) gf_malloc(sizeof(GF_RTPBox)); rtp->subType = GF_ISOM_BOX_TYPE_SDP; rtp->type = GF_ISOM_BOX_TYPE_RTP; rtp->sdpText = NULL; hnti_AddBox(hnti, (GF_Box *)rtp); } rtp = (GF_RTPBox *) hnti->SDP; if (!rtp->sdpText) { rtp->sdpText = (char*)gf_malloc(sizeof(char) * (strlen(text) + 3)); strcpy(rtp->sdpText, text); strcat(rtp->sdpText, "\r\n"); return GF_OK; } buf = (char*)gf_malloc(sizeof(char) * (strlen(rtp->sdpText) + strlen(text) + 3)); strcpy(buf, rtp->sdpText); strcat(buf, text); strcat(buf, "\r\n"); gf_free(rtp->sdpText); ReorderSDP(buf, GF_TRUE); rtp->sdpText = buf; return GF_OK; }
GF_MetaBox *gf_isom_apple_create_meta_extensions(GF_ISOFile *mov) { GF_Err e; u32 i; GF_MetaBox *meta; GF_UserDataMap *map; if (!mov || !mov->moov) return NULL; if (!mov->moov->udta) { e = moov_AddBox((GF_Box*)mov->moov, gf_isom_box_new(GF_ISOM_BOX_TYPE_UDTA)); if (e) return NULL; } map = udta_getEntry(mov->moov->udta, GF_ISOM_BOX_TYPE_META, NULL); if (map) { for(i = 0; i < gf_list_count(map->other_boxes); i++) { meta = (GF_MetaBox*)gf_list_get(map->other_boxes, i); if(meta != NULL && meta->handler != NULL && meta->handler->handlerType == GF_ISOM_HANDLER_TYPE_MDIR) return meta; } } meta = (GF_MetaBox *)gf_isom_box_new(GF_ISOM_BOX_TYPE_META); if(meta != NULL) { meta->handler = (GF_HandlerBox *)gf_isom_box_new(GF_ISOM_BOX_TYPE_HDLR); if(meta->handler == NULL) { gf_isom_box_del((GF_Box *)meta); return NULL; } meta->handler->handlerType = GF_ISOM_HANDLER_TYPE_MDIR; if (!meta->other_boxes) meta->other_boxes = gf_list_new(); gf_list_add(meta->other_boxes, gf_isom_box_new(GF_ISOM_BOX_TYPE_ILST)); udta_AddBox(mov->moov->udta, (GF_Box *)meta); } return meta; }
GF_Err gf_isom_setup_hint_track(GF_ISOFile *movie, u32 trackNumber, u32 HintType) { GF_Err e; GF_TrackBox *trak; GF_TrackReferenceBox *tref; GF_TrackReferenceTypeBox *dpnd; GF_HintMediaHeaderBox *hmhd; //UDTA related ... GF_UserDataBox *udta; //what do we support switch (HintType) { case GF_ISOM_HINT_RTP: break; default: return GF_NOT_SUPPORTED; } e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE); if (e) return e; trak = gf_isom_get_track_from_file(movie, trackNumber); if (!trak) return gf_isom_last_error(movie); //check we have a hint ... if ( !IsHintTrack(trak)) { return GF_BAD_PARAM; } hmhd = (GF_HintMediaHeaderBox *)trak->Media->information->InfoHeader; //make sure the subtype was not already defined if (hmhd->subType) return GF_BAD_PARAM; //store the HintTrack format for later use... hmhd->subType = HintType; //hint tracks always have a tref and everything ... if (!trak->References) { if (!trak->References) { tref = (GF_TrackReferenceBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_TREF); e = trak_AddBox((GF_Box*)trak, (GF_Box *)tref); if (e) return e; } } tref = trak->References; //do we have a hint reference on this trak ??? e = Track_FindRef(trak, GF_ISOM_BOX_TYPE_HINT, &dpnd); if (e) return e; //if yes, return false (existing hint track...) if (dpnd) return GF_BAD_PARAM; //create our dep dpnd = (GF_TrackReferenceTypeBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_REFT); dpnd->reference_type = GF_ISOM_BOX_TYPE_HINT; e = tref_AddBox((GF_Box*)tref, (GF_Box *) dpnd); if (e) return e; //for RTP, we need to do some UDTA-related stuff... if (HintType != GF_ISOM_HINT_RTP) return GF_OK; if (!trak->udta) { //create one udta = (GF_UserDataBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_UDTA); e = trak_AddBox((GF_Box*)trak, (GF_Box *) udta); if (e) return e; } udta = trak->udta; //HNTI e = udta_AddBox(udta, gf_isom_box_new(GF_ISOM_BOX_TYPE_HNTI)); if (e) return e; /* //NAME e = udta_AddBox(udta, gf_isom_box_new(GF_ISOM_BOX_TYPE_NAME)); if (e) return e; //HINF return udta_AddBox(udta, gf_isom_box_new(GF_ISOM_BOX_TYPE_HINF)); */ return GF_OK; }