GF_Err gf_cenc_set_pssh(GF_ISOFile *mp4, bin128 systemID, u32 version, u32 KID_count, bin128 *KIDs, char *data, u32 len) { GF_ProtectionSystemHeaderBox *pssh; pssh = (GF_ProtectionSystemHeaderBox *)pssh_New(); if (!pssh) return GF_IO_ERR; memmove((char *)pssh->SystemID, systemID, 16); pssh->version = version; if (version) { pssh->KID_count = KID_count; if (KID_count) { if (!pssh->KIDs) pssh->KIDs = (bin128 *)gf_malloc(pssh->KID_count*sizeof(bin128)); memmove(pssh->KIDs, KIDs, pssh->KID_count*sizeof(bin128)); } } pssh->private_data_size = len; if (!pssh->private_data) pssh->private_data = (u8 *)gf_malloc(pssh->private_data_size*sizeof(char)); memmove((char *)pssh->private_data, data, pssh->private_data_size); if (!mp4->moov->other_boxes) mp4->moov->other_boxes = gf_list_new(); gf_list_add(mp4->moov->other_boxes, pssh); return GF_OK; }
GF_Err MergeFragment(GF_MovieFragmentBox *moof, GF_ISOFile *mov) { GF_Err e; u32 i, j; u64 MaxDur; GF_TrackFragmentBox *traf; GF_TrackBox *trak; MaxDur = 0; //we shall have a MOOV and its MVEX BEFORE any MOOF if (!mov->moov || !mov->moov->mvex) { GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Error: %s not received before merging fragment\n", mov->moov ? "mvex" : "moov" )); return GF_ISOM_INVALID_FILE; } //and all fragments must be continous - we do not throw an error as we may still want to be able to concatenate dependent representations in DASH and //we will likely a-have R1(moofSN 1, 3, 5, 7) plus R2(moofSN 2, 4, 6, 8) if (mov->NextMoofNumber && (mov->NextMoofNumber >= moof->mfhd->sequence_number)) { GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Warning: wrong sequence number: got %d but last one was %d\n", moof->mfhd->sequence_number, mov->NextMoofNumber)); // return GF_ISOM_INVALID_FILE; } i=0; while ((traf = (GF_TrackFragmentBox*)gf_list_enum(moof->TrackList, &i))) { if (!traf->tfhd) { trak = NULL; traf->trex = NULL; } else { trak = gf_isom_get_track_from_id(mov->moov, traf->tfhd->trackID); j=0; while ((traf->trex = (GF_TrackExtendsBox*)gf_list_enum(mov->moov->mvex->TrackExList, &j))) { if (traf->trex->trackID == traf->tfhd->trackID) break; traf->trex = NULL; } } if (!trak || !traf->trex) { GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Error: Cannot find fragment track with ID %d\n", traf->tfhd->trackID)); return GF_ISOM_INVALID_FILE; } e = MergeTrack(trak, traf, mov->current_top_box_start, !trak->first_traf_merged); if (e) return e; trak->present_in_scalable_segment = 1; //update trak duration SetTrackDuration(trak); if (trak->Header->duration > MaxDur) MaxDur = trak->Header->duration; trak->first_traf_merged = 1; } if (moof->other_boxes) { GF_Box *a; i = 0; while ((a = (GF_Box *)gf_list_enum(moof->other_boxes, &i))) { if (a->type == GF_ISOM_BOX_TYPE_PSSH) { GF_ProtectionSystemHeaderBox *pssh = (GF_ProtectionSystemHeaderBox *)pssh_New(); memmove(pssh->SystemID, ((GF_ProtectionSystemHeaderBox *)a)->SystemID, 16); pssh->KID_count = ((GF_ProtectionSystemHeaderBox *)a)->KID_count; pssh->KIDs = (bin128 *)gf_malloc(pssh->KID_count*sizeof(bin128)); memmove(pssh->KIDs, ((GF_ProtectionSystemHeaderBox *)a)->KIDs, pssh->KID_count*sizeof(bin128)); pssh->private_data_size = ((GF_ProtectionSystemHeaderBox *)a)->private_data_size; pssh->private_data = (u8 *)gf_malloc(pssh->private_data_size*sizeof(char)); memmove(pssh->private_data, ((GF_ProtectionSystemHeaderBox *)a)->private_data, pssh->private_data_size); if (!mov->moov->other_boxes) mov->moov->other_boxes = gf_list_new(); gf_list_add(mov->moov->other_boxes, pssh); } } } mov->NextMoofNumber = moof->mfhd->sequence_number; //update movie duration if (mov->moov->mvhd->duration < MaxDur) mov->moov->mvhd->duration = MaxDur; return GF_OK; }