GF_Err senc_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; u32 sample_count; GF_SampleEncryptionBox *ptr = (GF_SampleEncryptionBox *) s; e = gf_isom_box_write_header(s, bs); if (e) return e; //WARNING - PSEC (UUID) IS TYPECASTED TO SENC (FULL BOX) SO WE CANNOT USE USUAL FULL BOX FUNCTIONS gf_bs_write_u8(bs, ptr->version); gf_bs_write_u24(bs, ptr->flags); sample_count = gf_list_count(ptr->samp_aux_info); gf_bs_write_u32(bs, sample_count); if (sample_count) { u32 i, j; e = store_senc_info(ptr, bs); if (e) return e; for (i = 0; i < sample_count; i++) { GF_CENCSampleAuxInfo *sai = (GF_CENCSampleAuxInfo *)gf_list_get(ptr->samp_aux_info, i); //for cbcs scheme, IV_size is 0, constant IV shall be used. It is written in tenc box rather than in sai if (sai->IV_size) gf_bs_write_data(bs, (char *)sai->IV, sai->IV_size); if (ptr->flags & 0x00000002) { gf_bs_write_u16(bs, sai->subsample_count); for (j = 0; j < sai->subsample_count; j++) { gf_bs_write_u16(bs, sai->subsamples[j].bytes_clear_data); gf_bs_write_u32(bs, sai->subsamples[j].bytes_encrypted_data); } } } } return GF_OK; }
GF_Err schm_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; GF_SchemeTypeBox *ptr = (GF_SchemeTypeBox *) s; if (!s) return GF_BAD_PARAM; e = gf_isom_full_box_write(s, bs); gf_bs_write_u32(bs, ptr->scheme_type); gf_bs_write_u32(bs, ptr->scheme_version); if (ptr->flags & 0x000001) gf_bs_write_data(bs, ptr->URI, strlen(ptr->URI)+1); return GF_OK; }
GF_Err Write_StreamDescDTE(GF_StreamDescDTE *dte, GF_BitStream *bs) { gf_bs_write_u8(bs, dte->source); gf_bs_write_u8(bs, dte->trackRefIndex); gf_bs_write_u16(bs, dte->dataLength); gf_bs_write_u32(bs, dte->streamDescIndex); gf_bs_write_u32(bs, dte->byteOffset); gf_bs_write_u32(bs, dte->reserved); return GF_OK; }
GF_Err Write_SampleDTE(GF_SampleDTE *dte, GF_BitStream *bs) { gf_bs_write_u8(bs, dte->source); gf_bs_write_u8(bs, dte->trackRefIndex); gf_bs_write_u16(bs, dte->dataLength); gf_bs_write_u32(bs, dte->sampleNumber); gf_bs_write_u32(bs, dte->byteOffset); gf_bs_write_u16(bs, dte->bytesPerComp); gf_bs_write_u16(bs, dte->samplesPerComp); return GF_OK; }
GF_Err btrt_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; GF_MPEG4BitRateBox *ptr = (GF_MPEG4BitRateBox *) s; if (!s) return GF_BAD_PARAM; e = gf_isom_box_write_header(s, bs); if (e) return e; gf_bs_write_u32(bs, ptr->bufferSizeDB); gf_bs_write_u32(bs, ptr->maxBitrate); gf_bs_write_u32(bs, ptr->avgBitrate); return GF_OK; }
static void gf_isom_write_tx3g(GF_Tx3gSampleEntryBox *a, GF_BitStream *bs, u32 sidx, u32 sidx_offset) { u32 size, j, fount_count; void gpp_write_rgba(GF_BitStream *bs, u32 col); void gpp_write_box(GF_BitStream *bs, GF_BoxRecord *rec); void gpp_write_style(GF_BitStream *bs, GF_StyleRecord *rec); if (sidx_offset) gf_bs_write_u8(bs, sidx + sidx_offset); /*SINCE WINCE HAS A READONLY VERSION OF MP4 WE MUST DO IT BY HAND*/ size = 8 + 18 + 8 + 12; size += 8 + 2; fount_count = 0; if (a->font_table) { fount_count = a->font_table->entry_count; for (j = 0; j<fount_count; j++) { size += 3; if (a->font_table->fonts[j].fontName) size += (u32)strlen(a->font_table->fonts[j].fontName); } } /*write TextSampleEntry box*/ gf_bs_write_u32(bs, size); gf_bs_write_u32(bs, a->type); gf_bs_write_data(bs, a->reserved, 6); gf_bs_write_u16(bs, a->dataReferenceIndex); gf_bs_write_u32(bs, a->displayFlags); gf_bs_write_u8(bs, a->horizontal_justification); gf_bs_write_u8(bs, a->vertical_justification); gpp_write_rgba(bs, a->back_color); gpp_write_box(bs, &a->default_box); gpp_write_style(bs, &a->default_style); /*write font table box*/ size -= (8 + 18 + 8 + 12); gf_bs_write_u32(bs, size); gf_bs_write_u32(bs, GF_ISOM_BOX_TYPE_FTAB); gf_bs_write_u16(bs, fount_count); for (j = 0; j<fount_count; j++) { gf_bs_write_u16(bs, a->font_table->fonts[j].fontID); if (a->font_table->fonts[j].fontName) { u32 len = (u32)strlen(a->font_table->fonts[j].fontName); gf_bs_write_u8(bs, len); gf_bs_write_data(bs, a->font_table->fonts[j].fontName, len); } else { gf_bs_write_u8(bs, 0); } } }
GF_Err gppc_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; GF_3GPPConfigBox *ptr = (GF_3GPPConfigBox *)s; e = gf_isom_box_write_header(s, bs); if (e) return e; gf_bs_write_u32(bs, ptr->cfg.vendor); gf_bs_write_u8(bs, ptr->cfg.decoder_version); switch (ptr->cfg.type) { case GF_ISOM_SUBTYPE_3GP_H263: gf_bs_write_u8(bs, ptr->cfg.H263_level); gf_bs_write_u8(bs, ptr->cfg.H263_profile); break; case GF_ISOM_SUBTYPE_3GP_AMR: case GF_ISOM_SUBTYPE_3GP_AMR_WB: gf_bs_write_u16(bs, ptr->cfg.AMR_mode_set); gf_bs_write_u8(bs, ptr->cfg.AMR_mode_change_period); gf_bs_write_u8(bs, ptr->cfg.frames_per_sample); break; case GF_ISOM_SUBTYPE_3GP_EVRC: case GF_ISOM_SUBTYPE_3GP_QCELP: case GF_ISOM_SUBTYPE_3GP_SMV: gf_bs_write_u8(bs, ptr->cfg.frames_per_sample); break; } return GF_OK; }
GF_Err iloc_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; u32 i, j, item_count, extent_count; GF_ItemLocationBox *ptr = (GF_ItemLocationBox *)s; if (!s) return GF_BAD_PARAM; e = gf_isom_full_box_write(s, bs); if (e) return e; gf_bs_write_int(bs, ptr->offset_size, 4); gf_bs_write_int(bs, ptr->length_size, 4); gf_bs_write_int(bs, ptr->base_offset_size, 4); gf_bs_write_int(bs, ptr->index_size, 4); item_count = gf_list_count(ptr->location_entries); if (ptr->version < 2) { gf_bs_write_u16(bs, item_count); } else { gf_bs_write_u32(bs, item_count); } for (i = 0; i < item_count; i++) { GF_ItemLocationEntry *location = (GF_ItemLocationEntry *)gf_list_get(ptr->location_entries, i); if (ptr->version < 2) { gf_bs_write_u16(bs, location->item_ID); } else { gf_bs_write_u32(bs, location->item_ID); } if (ptr->version == 1 || ptr->version == 2) { gf_bs_write_u16(bs, location->construction_method); } gf_bs_write_u16(bs, location->data_reference_index); gf_bs_write_long_int(bs, location->base_offset, 8*ptr->base_offset_size); extent_count = gf_list_count(location->extent_entries); gf_bs_write_u16(bs, extent_count); for (j=0; j<extent_count; j++) { GF_ItemExtentEntry *extent = (GF_ItemExtentEntry *)gf_list_get(location->extent_entries, j); if ((ptr->version == 1 || ptr->version == 2) && ptr->index_size > 0) { gf_bs_write_long_int(bs, extent->extent_index, 8 * ptr->index_size); } gf_bs_write_long_int(bs, extent->extent_offset, 8*ptr->offset_size); gf_bs_write_long_int(bs, extent->extent_length, 8*ptr->length_size); } } return GF_OK; }
GF_Err gf_isom_hint_rtp_write(GF_RTPPacket *ptr, GF_BitStream *bs) { GF_Err e; u32 TLVcount, DTEcount, i; GF_Box none; GF_GenericDTE *dte; gf_bs_write_u32(bs, ptr->relativeTransTime); //RTP Header // gf_bs_write_int(bs, 2, 2); //version is 2 gf_bs_write_int(bs, 2, 2); gf_bs_write_int(bs, ptr->P_bit, 1); gf_bs_write_int(bs, ptr->X_bit, 1); gf_bs_write_int(bs, 0, 4); gf_bs_write_int(bs, ptr->M_bit, 1); gf_bs_write_int(bs, ptr->payloadType, 7); gf_bs_write_u16(bs, ptr->SequenceNumber); gf_bs_write_int(bs, 0, 13); TLVcount = gf_list_count(ptr->TLV); DTEcount = gf_list_count(ptr->DataTable); gf_bs_write_int(bs, TLVcount ? 1 : 0, 1); gf_bs_write_int(bs, ptr->B_bit, 1); gf_bs_write_int(bs, ptr->R_bit, 1); gf_bs_write_u16(bs, DTEcount); if (TLVcount) { //first write the size of the table ... none.size = 4; //WE INCLUDE THE SIZE FIELD LENGTH none.type = 0; gf_isom_box_array_size(&none, ptr->TLV); gf_bs_write_u32(bs, (u32) none.size); e = gf_isom_box_array_write(&none, ptr->TLV, bs); if (e) return e; } //write the DTE... for (i = 0; i < DTEcount; i++) { dte = (GF_GenericDTE *)gf_list_get(ptr->DataTable, i); e = WriteDTE(dte, bs); if (e) return e; } return GF_OK; }
GF_Err infe_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; u32 len; GF_ItemInfoEntryBox *ptr = (GF_ItemInfoEntryBox *)s; if (!s) return GF_BAD_PARAM; e = gf_isom_full_box_write(s, bs); if (e) return e; if (ptr->version == 3) { gf_bs_write_u32(bs, ptr->item_ID); } else { gf_bs_write_u16(bs, ptr->item_ID); } gf_bs_write_u16(bs, ptr->item_protection_index); if (ptr->version >= 2) { gf_bs_write_u32(bs, ptr->item_type); } if (ptr->item_name) { len = (u32) strlen(ptr->item_name)+1; gf_bs_write_data(bs, ptr->item_name, len); } else { gf_bs_write_byte(bs, 0, 1); } if (ptr->item_type == GF_META_ITEM_TYPE_MIME || ptr->item_type == GF_META_ITEM_TYPE_URI) { if (ptr->content_type) { len = (u32)strlen(ptr->content_type) + 1; gf_bs_write_data(bs, ptr->content_type, len); } else { gf_bs_write_byte(bs, 0, 1); } } if (ptr->item_type == GF_META_ITEM_TYPE_MIME) { if (ptr->content_encoding) { len = (u32)strlen(ptr->content_encoding) + 1; gf_bs_write_data(bs, ptr->content_encoding, len); } else { gf_bs_write_byte(bs, 0, 1); } } return GF_OK; }
static void rewrite_nalus_list(GF_List *nalus, GF_BitStream *bs, Bool rewrite_start_codes, u32 nal_unit_size_field) { u32 i, count = gf_list_count(nalus); for (i=0; i<count; i++) { GF_AVCConfigSlot *sl = gf_list_get(nalus, i); if (rewrite_start_codes) gf_bs_write_u32(bs, 1); else gf_bs_write_int(bs, sl->size, 8*nal_unit_size_field); gf_bs_write_data(bs, sl->data, sl->size); } }
GF_Err frma_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; GF_OriginalFormatBox *ptr = (GF_OriginalFormatBox *)s; if (!s) return GF_BAD_PARAM; e = gf_isom_box_write_header(s, bs); if (e) return e; gf_bs_write_u32(bs, ptr->data_format); return GF_OK; }
static GF_Err JP2_AttachStream(GF_BaseDecoder *ifcg, GF_ESD *esd) { GF_BitStream *bs; JP2CTX(); if (esd->dependsOnESID || esd->decoderConfig->upstream) return GF_NOT_SUPPORTED; if (!esd->decoderConfig->decoderSpecificInfo) return GF_OK; if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_IMAGE_JPEG_2000) { bs = gf_bs_new(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, GF_BITSTREAM_READ); ctx->height = gf_bs_read_u32(bs); ctx->width = gf_bs_read_u32(bs); ctx->nb_comp = gf_bs_read_u16(bs); ctx->bpp = 1 + gf_bs_read_u8(bs); ctx->out_size = ctx->width * ctx->height * ctx->nb_comp /* * ctx->bpp / 8 */; gf_bs_del(bs); switch (ctx->nb_comp) { case 1: ctx->pixel_format = GF_PIXEL_GREYSCALE; break; case 2: ctx->pixel_format = GF_PIXEL_ALPHAGREY; break; case 3: ctx->pixel_format = GF_PIXEL_RGB_24; break; case 4: ctx->pixel_format = GF_PIXEL_RGBA; break; default: return GF_NOT_SUPPORTED; } } else { bs = gf_bs_new(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, GF_BITSTREAM_READ); gf_bs_read_u32(bs); ctx->width = gf_bs_read_u16(bs); ctx->height = gf_bs_read_u16(bs); gf_bs_del(bs); bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); gf_bs_write_u32(bs, 12); gf_bs_write_u32(bs, GF_4CC('j','P',' ',' ') ); gf_bs_write_u32(bs, 0x0D0A870A); gf_bs_write_u32(bs, 20); gf_bs_write_u32(bs, GF_4CC('f','t','y','p') ); gf_bs_write_u32(bs, GF_4CC('j','p','2',' ') ); gf_bs_write_u32(bs, 0); gf_bs_write_u32(bs, GF_4CC('j','p','2',' ') ); gf_bs_write_data(bs, esd->decoderConfig->decoderSpecificInfo->data+8, esd->decoderConfig->decoderSpecificInfo->dataLength-8); gf_bs_get_content(bs, &ctx->dsi, &ctx->dsi_size); gf_bs_del(bs); ctx->nb_comp = 3; ctx->out_size = 3*ctx->width*ctx->height/2; ctx->pixel_format = GF_PIXEL_YV12; } return GF_OK; }
GF_Err piff_pssh_Write(GF_Box *s, GF_BitStream *bs) { GF_PIFFProtectionSystemHeaderBox *ptr = (GF_PIFFProtectionSystemHeaderBox *) s; GF_Err e = gf_isom_full_box_write(s, bs); if (e) return e; gf_bs_write_data(bs, (char *) ptr->SystemID, 16); gf_bs_write_u32(bs, ptr->private_data_size); gf_bs_write_data(bs, (char *) ptr->private_data, ptr->private_data_size); return GF_OK; }
GF_Err store_senc_info(GF_SampleEncryptionBox *ptr, GF_BitStream *bs) { GF_Err e; u64 pos; if (!ptr->cenc_saio) return GF_OK; pos = gf_bs_get_position(bs); if (pos>0xFFFFFFFFULL) { GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] \"senc\" offset larger than 32-bits , cannot store.\n")); return GF_NOT_SUPPORTED; } e = gf_bs_seek(bs, ptr->cenc_saio->offset_first_offset_field); if (e) return e; if (ptr->traf) { gf_bs_write_u32(bs, (u32) ( pos - ptr->traf->moof_start_in_bs) ); } else { gf_bs_write_u32(bs, (u32) pos); } return gf_bs_seek(bs, pos); }
Bool uir_on_event_record(GF_UIRecord *uir , GF_Event *event, Bool consumed_by_compositor) { switch (event->type) { case GF_EVENT_CONNECT: if (event->connect.is_connected) { uir->ck = uir->term->root_scene->scene_codec ? uir->term->root_scene->scene_codec->ck : uir->term->root_scene->dyn_ck; } break; case GF_EVENT_CLICK: case GF_EVENT_MOUSEUP: case GF_EVENT_MOUSEDOWN: case GF_EVENT_MOUSEOVER: case GF_EVENT_MOUSEOUT: /*!! ALL MOUSE EVENTS SHALL BE DECLARED BEFORE MOUSEMOVE !! */ case GF_EVENT_MOUSEMOVE: /*mouse wheel event*/ case GF_EVENT_MOUSEWHEEL: gf_bs_write_u32(uir->bs, gf_clock_time(uir->ck) ); gf_bs_write_u8(uir->bs, event->type); gf_bs_write_u8(uir->bs, event->mouse.button); gf_bs_write_u32(uir->bs, event->mouse.x); gf_bs_write_u32(uir->bs, event->mouse.y); gf_bs_write_float(uir->bs, FIX2FLT(event->mouse.wheel_pos) ); gf_bs_write_u8(uir->bs, event->mouse.key_states); break; /*Key Events*/ case GF_EVENT_KEYUP: case GF_EVENT_KEYDOWN: case GF_EVENT_LONGKEYPRESS: gf_bs_write_u32(uir->bs, gf_clock_time(uir->ck) ); gf_bs_write_u8(uir->bs, event->type); gf_bs_write_u32(uir->bs, event->key.key_code); gf_bs_write_u32(uir->bs, event->key.hw_code); gf_bs_write_u32(uir->bs, event->key.flags); break; /*character input*/ case GF_EVENT_TEXTINPUT: gf_bs_write_u32(uir->bs, gf_clock_time(uir->ck) ); gf_bs_write_u8(uir->bs, event->type); gf_bs_write_u32(uir->bs, event->character.unicode_char); break; } return 0; }
GF_Err pssh_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; GF_ProtectionSystemHeaderBox *ptr = (GF_ProtectionSystemHeaderBox *) s; if (!s) return GF_BAD_PARAM; e = gf_isom_full_box_write(s, bs); if (e) return e; gf_bs_write_data(bs, (char *) ptr->SystemID, 16); if (ptr->version > 0) { u32 i; gf_bs_write_u32(bs, ptr->KID_count); for (i=0; i<ptr->KID_count; i++) gf_bs_write_data(bs, (char *) ptr->KIDs[i], 16); } if (ptr->private_data) { gf_bs_write_u32(bs, ptr->private_data_size); gf_bs_write_data(bs, (char *) ptr->private_data, ptr->private_data_size); } else gf_bs_write_u32(bs, 0); return GF_OK; }
static GF_ESD* get_esd() { GF_BitStream *dsi = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); GF_ESD *esd = gf_odf_desc_esd_new(0); esd->ESID = 1; esd->decoderConfig->streamType = GF_STREAM_AUDIO; esd->decoderConfig->objectTypeIndication = GPAC_OTI_RAW_MEDIA_STREAM; esd->decoderConfig->avgBitrate = esd->decoderConfig->maxBitrate = 0; esd->slConfig->timestampResolution = FM_FAKE_PULL_AUDIO_FREQ; /*Decoder Specific Info for raw media*/ gf_bs_write_u32(dsi, FM_FAKE_PULL_AUDIO_FREQ); /*u32 sample_rate*/ gf_bs_write_u16(dsi, FM_FAKE_PULL_CHAN_NUM); /*u16 nb_channels*/ gf_bs_write_u16(dsi, FM_FAKE_PULL_BITS); /*u16 nb_bits_per_sample*/ gf_bs_write_u32(dsi, FM_FAKE_PULL_FRAME_LEN); /*u32 frame_size*/ gf_bs_write_u32(dsi, 0); /*u32 channel_config*/ gf_bs_get_content(dsi, &esd->decoderConfig->decoderSpecificInfo->data, &esd->decoderConfig->decoderSpecificInfo->dataLength); gf_bs_del(dsi); return esd; }
GF_Err ghnt_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; GF_HintSampleEntryBox *ptr = (GF_HintSampleEntryBox *)s; e = gf_isom_box_write_header(s, bs); if (e) return e; gf_bs_write_data(bs, ptr->reserved, 6); gf_bs_write_u16(bs, ptr->dataReferenceIndex); gf_bs_write_u16(bs, ptr->HintTrackVersion); gf_bs_write_u16(bs, ptr->LastCompatibleVersion); gf_bs_write_u32(bs, ptr->MaxPacketSize); return GF_OK; }
GF_Err piff_psec_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; u32 sample_count; GF_SampleEncryptionBox *ptr = (GF_SampleEncryptionBox *) s; if (!s) return GF_BAD_PARAM; e = gf_isom_box_write_header(s, bs); if (e) return e; gf_bs_write_u8(bs, ptr->version); gf_bs_write_u24(bs, ptr->flags); if (ptr->flags & 1) { gf_bs_write_int(bs, ptr->AlgorithmID, 24); gf_bs_write_u8(bs, ptr->IV_size); gf_bs_write_data(bs, (char *) ptr->KID, 16); } sample_count = gf_list_count(ptr->samp_aux_info); gf_bs_write_u32(bs, sample_count); if (sample_count) { u32 i, j; e = store_senc_info((GF_SampleEncryptionBox *)ptr, bs); if (e) return e; for (i = 0; i < sample_count; i++) { GF_CENCSampleAuxInfo *sai = (GF_CENCSampleAuxInfo *)gf_list_get(ptr->samp_aux_info, i); if (! sai->IV_size) continue; gf_bs_write_data(bs, (char *)sai->IV, sai->IV_size); gf_bs_write_u16(bs, sai->subsample_count); for (j = 0; j < sai->subsample_count; j++) { gf_bs_write_u16(bs, sai->subsamples[j].bytes_clear_data); gf_bs_write_u32(bs, sai->subsamples[j].bytes_encrypted_data); } } } return GF_OK; }
void gf_isom_audio_sample_entry_write(GF_AudioSampleEntryBox *ptr, GF_BitStream *bs) { gf_bs_write_data(bs, ptr->reserved, 6); gf_bs_write_u16(bs, ptr->dataReferenceIndex); gf_bs_write_u16(bs, ptr->version); gf_bs_write_u16(bs, ptr->revision); gf_bs_write_u32(bs, ptr->vendor); gf_bs_write_u16(bs, ptr->channel_count); gf_bs_write_u16(bs, ptr->bitspersample); gf_bs_write_u16(bs, ptr->compression_id); gf_bs_write_u16(bs, ptr->packet_size); gf_bs_write_u16(bs, ptr->samplerate_hi); gf_bs_write_u16(bs, ptr->samplerate_lo); }
GF_Err piff_pssh_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; GF_PIFFProtectionSystemHeaderBox *ptr = (GF_PIFFProtectionSystemHeaderBox *) s; if (!s) return GF_BAD_PARAM; e = gf_isom_box_write_header(s, bs); if (e) return e; gf_bs_write_u8(bs, ptr->version); gf_bs_write_u24(bs, ptr->flags); gf_bs_write_data(bs, (char *) ptr->SystemID, 16); gf_bs_write_u32(bs, ptr->private_data_size); gf_bs_write_data(bs, (char *) ptr->private_data, ptr->private_data_size); return GF_OK; }
/*Dummy input just send a file name, no multitrack to handle so we don't need to check sub_url nor expected type*/ static GF_Descriptor *DC_GetServiceDesc(GF_InputService *plug, u32 expect_type, const char *sub_url) { u32 size = 0; char *uri; GF_ESD *esd; GF_BitStream *bs; DCReader *read = (DCReader *) plug->priv; GF_InitialObjectDescriptor *iod = (GF_InitialObjectDescriptor *) gf_odf_desc_new(GF_ODF_IOD_TAG); iod->scene_profileAndLevel = 1; iod->graphics_profileAndLevel = 1; iod->OD_profileAndLevel = 1; iod->audio_profileAndLevel = 0xFE; iod->visual_profileAndLevel = 0xFE; iod->objectDescriptorID = 1; if (read->is_views_url) { iod->URLString = gf_strdup(read->url); return (GF_Descriptor *)iod; } esd = gf_odf_desc_esd_new(0); esd->slConfig->timestampResolution = 1000; esd->slConfig->useTimestampsFlag = 1; esd->ESID = 0xFFFE; esd->decoderConfig->streamType = GF_STREAM_PRIVATE_SCENE; esd->decoderConfig->objectTypeIndication = read->oti; if (read->dnload) { uri = (char *) gf_dm_sess_get_cache_name(read->dnload); gf_dm_sess_get_stats(read->dnload, NULL, NULL, &size, NULL, NULL, NULL); } else { FILE *f = gf_fopen(read->url, "rt"); gf_fseek(f, 0, SEEK_END); size = (u32) gf_ftell(f); gf_fclose(f); uri = read->url; } bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); gf_bs_write_u32(bs, size); gf_bs_write_data(bs, uri, (u32) strlen(uri)); gf_bs_get_content(bs, &esd->decoderConfig->decoderSpecificInfo->data, &esd->decoderConfig->decoderSpecificInfo->dataLength); gf_bs_del(bs); gf_list_add(iod->ESDescriptors, esd); return (GF_Descriptor *)iod; }
GF_Err MCDec_InitMpeg4Decoder(MCDec *ctx) { char *dsi_data = NULL; u32 dsi_data_size = 0; if (!ctx->esd->decoderConfig->decoderSpecificInfo) { ctx->esd->decoderConfig->decoderSpecificInfo = (GF_DefaultDescriptor *) gf_odf_desc_new(GF_ODF_DSI_TAG); } if (ctx->esd->decoderConfig->decoderSpecificInfo->data) { GF_M4VDecSpecInfo vcfg; GF_BitStream *bs; gf_m4v_get_config(ctx->esd->decoderConfig->decoderSpecificInfo->data, ctx->esd->decoderConfig->decoderSpecificInfo->dataLength, &vcfg); ctx->width = vcfg.width; ctx->height = vcfg.height; if (ctx->esd->slConfig) { ctx->esd->slConfig->predefined = 2; } bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); gf_bs_write_u32(bs, 0); gf_odf_desc_write_bs((GF_Descriptor *) ctx->esd, bs); gf_bs_get_content(bs, &dsi_data, &dsi_data_size); gf_bs_del(bs); ctx->mime = "video/mp4v-es"; char *esds = (char *)malloc(dsi_data_size); memcpy(esds, dsi_data, dsi_data_size); esds[0] = 0x00; esds[1] = 0x00; esds[2] = 0x00; esds[3] = 0x01; AMediaFormat_setBuffer(ctx->format, "csd-0", esds, dsi_data_size); gf_free(dsi_data); return GF_OK; } return GF_NOT_SUPPORTED; }
GF_Err iinf_Write(GF_Box *s, GF_BitStream *bs) { u32 count; GF_Err e; GF_ItemInfoBox *ptr = (GF_ItemInfoBox *)s; if (!s) return GF_BAD_PARAM; e = gf_isom_full_box_write(s, bs); if (e) return e; count = gf_list_count(ptr->item_infos); if (ptr->version == 0) gf_bs_write_u16(bs, count); else gf_bs_write_u32(bs, count); if (count) { gf_isom_box_array_write(s, ptr->item_infos, bs); } return GF_OK; }
GF_Err piff_psec_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; GF_PIFFSampleEncryptionBox *ptr = (GF_PIFFSampleEncryptionBox *) s; if (!s) return GF_BAD_PARAM; e = gf_isom_box_write_header(s, bs); if (e) return e; gf_bs_write_u8(bs, ptr->version); gf_bs_write_u24(bs, ptr->flags); if (ptr->flags & 1) { gf_bs_write_int(bs, ptr->AlgorithmID, 24); gf_bs_write_u8(bs, ptr->IV_size); gf_bs_write_data(bs, (char *) ptr->KID, 16); } gf_bs_write_u32(bs, ptr->sample_count); if (ptr->cenc_data && ptr->cenc_data_size) { gf_bs_write_data(bs, ptr->cenc_data, ptr->cenc_data_size); } return GF_OK; }
void gf_isom_video_sample_entry_write(GF_VisualSampleEntryBox *ptr, GF_BitStream *bs) { gf_bs_write_data(bs, ptr->reserved, 6); gf_bs_write_u16(bs, ptr->dataReferenceIndex); gf_bs_write_u16(bs, ptr->version); gf_bs_write_u16(bs, ptr->revision); gf_bs_write_u32(bs, ptr->vendor); gf_bs_write_u32(bs, ptr->temporal_quality); gf_bs_write_u32(bs, ptr->spatial_quality); gf_bs_write_u16(bs, ptr->Width); gf_bs_write_u16(bs, ptr->Height); gf_bs_write_u32(bs, ptr->horiz_res); gf_bs_write_u32(bs, ptr->vert_res); gf_bs_write_u32(bs, ptr->entry_data_size); gf_bs_write_u16(bs, ptr->frames_per_sample); gf_bs_write_data(bs, ptr->compressor_name, 32); gf_bs_write_u16(bs, ptr->bit_depth); gf_bs_write_u16(bs, ptr->color_table_index); }
static GF_ESD *FFD_GetESDescriptor(FFDemux *ffd, Bool for_audio) { GF_BitStream *bs; Bool dont_use_sl; GF_ESD *esd = (GF_ESD *) gf_odf_desc_esd_new(0); esd->ESID = 1 + (for_audio ? ffd->audio_st : ffd->video_st); esd->decoderConfig->streamType = for_audio ? GF_STREAM_AUDIO : GF_STREAM_VISUAL; esd->decoderConfig->avgBitrate = esd->decoderConfig->maxBitrate = 0; /*remap std object types - depending on input formats, FFMPEG may not have separate DSI from initial frame. In this case we have no choice but using FFMPEG decoders*/ if (for_audio) { AVCodecContext *dec = ffd->ctx->streams[ffd->audio_st]->codec; esd->slConfig->timestampResolution = ffd->audio_tscale.den; switch (dec->codec_id) { case CODEC_ID_MP2: esd->decoderConfig->objectTypeIndication = GPAC_OTI_AUDIO_MPEG1; break; case CODEC_ID_MP3: esd->decoderConfig->objectTypeIndication = GPAC_OTI_AUDIO_MPEG2_PART3; break; case CODEC_ID_AAC: if (!dec->extradata_size) goto opaque_audio; esd->decoderConfig->objectTypeIndication = GPAC_OTI_AUDIO_AAC_MPEG4; esd->decoderConfig->decoderSpecificInfo->dataLength = dec->extradata_size; esd->decoderConfig->decoderSpecificInfo->data = gf_malloc(sizeof(char)*dec->extradata_size); memcpy(esd->decoderConfig->decoderSpecificInfo->data, dec->extradata, sizeof(char)*dec->extradata_size); break; default: opaque_audio: esd->decoderConfig->objectTypeIndication = GPAC_OTI_MEDIA_FFMPEG; bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); gf_bs_write_u32(bs, dec->codec_id); gf_bs_write_u32(bs, dec->sample_rate); gf_bs_write_u16(bs, dec->channels); gf_bs_write_u16(bs, dec->frame_size); gf_bs_write_u8(bs, 16); gf_bs_write_u8(bs, 0); /*ffmpeg specific*/ gf_bs_write_u16(bs, dec->block_align); gf_bs_write_u32(bs, dec->bit_rate); gf_bs_write_u32(bs, dec->codec_tag); if (dec->extradata_size) { gf_bs_write_data(bs, (char *) dec->extradata, dec->extradata_size); } gf_bs_get_content(bs, (char **) &esd->decoderConfig->decoderSpecificInfo->data, &esd->decoderConfig->decoderSpecificInfo->dataLength); gf_bs_del(bs); break; } dont_use_sl = ffd->unreliable_audio_timing; } else { AVCodecContext *dec = ffd->ctx->streams[ffd->video_st]->codec; esd->slConfig->timestampResolution = ffd->video_tscale.den; switch (dec->codec_id) { case CODEC_ID_MPEG4: /*there is a bug in fragmentation of raw H264 in ffmpeg, the NALU startcode (0x00000001) is split across two frames - we therefore force internal ffmpeg codec ID to avoid NALU size recompute at the decoder level*/ // case CODEC_ID_H264: /*if dsi not detected force use ffmpeg*/ if (!dec->extradata_size) goto opaque_video; /*otherwise use any MPEG-4 Visual*/ esd->decoderConfig->objectTypeIndication = (dec->codec_id==CODEC_ID_H264) ? GPAC_OTI_VIDEO_AVC : GPAC_OTI_VIDEO_MPEG4_PART2; esd->decoderConfig->decoderSpecificInfo->dataLength = dec->extradata_size; esd->decoderConfig->decoderSpecificInfo->data = gf_malloc(sizeof(char)*dec->extradata_size); memcpy(esd->decoderConfig->decoderSpecificInfo->data, dec->extradata, sizeof(char)*dec->extradata_size); break; case CODEC_ID_MPEG1VIDEO: esd->decoderConfig->objectTypeIndication = GPAC_OTI_VIDEO_MPEG1; break; case CODEC_ID_MPEG2VIDEO: esd->decoderConfig->objectTypeIndication = GPAC_OTI_VIDEO_MPEG2_422; break; default: opaque_video: esd->decoderConfig->objectTypeIndication = GPAC_OTI_MEDIA_FFMPEG; bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); gf_bs_write_u32(bs, dec->codec_id); gf_bs_write_u16(bs, dec->width); gf_bs_write_u16(bs, dec->height); /*ffmpeg specific*/ gf_bs_write_u32(bs, dec->bit_rate); gf_bs_write_u32(bs, dec->codec_tag); gf_bs_write_u32(bs, dec->pix_fmt); if (dec->extradata_size) { gf_bs_write_data(bs, (char *) dec->extradata, dec->extradata_size); } gf_bs_get_content(bs, (char **) &esd->decoderConfig->decoderSpecificInfo->data, &esd->decoderConfig->decoderSpecificInfo->dataLength); gf_bs_del(bs); break; } dont_use_sl = 0; } if (dont_use_sl) { esd->slConfig->predefined = SLPredef_SkipSL; } else { /*only send full AUs*/ esd->slConfig->useAccessUnitStartFlag = esd->slConfig->useAccessUnitEndFlag = 0; if (for_audio) { esd->slConfig->hasRandomAccessUnitsOnlyFlag = 1; } else { esd->slConfig->useRandomAccessPointFlag = 1; } esd->slConfig->useTimestampsFlag = 1; } return esd; }
static GF_Err gf_seng_encode_dims_au(GF_SceneEngine *seng, u16 ESID, GF_List *commands, char **data, u32 *size) { #ifndef GPAC_DISABLE_SCENE_DUMP GF_SceneDumper *dumper = NULL; #endif GF_Err e; char rad_name[4096]; char file_name[4096]; FILE *file = NULL; u64 fsize; char *buffer = NULL; GF_BitStream *bs = NULL; u8 dims_header; Bool compress_dims; #ifdef DUMP_DIMS_LOG_WITH_TIME u32 do_dump_with_time = 1; #endif u32 buffer_len; char *cache_dir, *dump_name; if (!data) return GF_BAD_PARAM; e = GF_OK; if (!seng->dump_path) cache_dir = gf_get_default_cache_directory(); else cache_dir = seng->dump_path; dump_name = "gpac_scene_engine_dump"; compress_dims = 1; #ifdef DUMP_DIMS_LOG_WITH_TIME start: #endif if (commands && gf_list_count(commands)) { sprintf(rad_name, "%s%c%s%s", cache_dir, GF_PATH_SEPARATOR, dump_name, "_update"); } else { #ifndef DUMP_DIMS_LOG_WITH_TIME sprintf(rad_name, "%s%c%s%s", cache_dir, GF_PATH_SEPARATOR, "rap_", dump_name); #else char date_str[100], time_str[100]; time_t now; struct tm *tm_tot; now = time(NULL); tm_tot = localtime(&now); strftime(date_str, 100, "%Yy%mm%dd", tm_tot); strftime(time_str, 100, "%Hh%Mm%Ss", tm_tot); sprintf(rad_name, "%s%c%s-%s-%s%s", cache_dir, GF_PATH_SEPARATOR, date_str, time_str, "rap_", dump_name); #endif } #ifndef GPAC_DISABLE_SCENE_DUMP dumper = gf_sm_dumper_new(seng->ctx->scene_graph, rad_name, ' ', GF_SM_DUMP_SVG); if (!dumper) { GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[SceneEngine] Cannot create SVG dumper for %s.svg\n", rad_name)); e = GF_IO_ERR; goto exit; } if (commands && gf_list_count(commands)) { e = gf_sm_dump_command_list(dumper, commands, 0, 0); } else { e = gf_sm_dump_graph(dumper, 0, 0); } gf_sm_dumper_del(dumper); if(seng->dump_rap){ GF_SceneDumper *dumper = NULL; sprintf(rad_name, "%s%c%s%s", cache_dir, GF_PATH_SEPARATOR, "rap_", dump_name); dumper = gf_sm_dumper_new(seng->ctx->scene_graph, rad_name, ' ', GF_SM_DUMP_SVG); if (!dumper) { GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[SceneEngine] Cannot create SVG dumper for %s.svg\n", rad_name)); e = GF_IO_ERR; goto exit; } e = gf_sm_dump_graph(dumper, 0, 0); gf_sm_dumper_del(dumper); } if (e) { GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[SceneEngine] Cannot dump DIMS Commands\n")); goto exit; } #endif #ifdef DUMP_DIMS_LOG_WITH_TIME if (do_dump_with_time) { do_dump_with_time = 0; goto start; } #endif sprintf(file_name, "%s.svg", rad_name); file = gf_f64_open(file_name, "rb"); if (!file) { GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[SceneEngine] Cannot open SVG dump file %s\n", file_name)); e = GF_IO_ERR; goto exit; } gf_f64_seek(file, 0, SEEK_END); fsize = gf_f64_tell(file); if (fsize == 0) { GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[SceneEngine] SVG dump %s is empty\n", file_name)); goto exit; } /* First, read the dump in a buffer */ buffer = gf_malloc((size_t)fsize * sizeof(char)); gf_f64_seek(file, 0, SEEK_SET); fsize = fread(buffer, sizeof(char), (size_t)fsize, file); fclose(file); file = NULL; /* Then, set DIMS unit header - TODO: notify redundant units*/ dims_header = 0; if (commands && gf_list_count(commands)) { dims_header = GF_DIMS_UNIT_P; /* streamer->all_non_rap_critical ? 0 : GF_DIMS_UNIT_P;*/ } else { /*redundant RAP with complete scene*/ dims_header = GF_DIMS_UNIT_M | GF_DIMS_UNIT_S | GF_DIMS_UNIT_I | GF_DIMS_UNIT_P; } /* Then, if compression is asked, we do it */ buffer_len = (u32)fsize; assert(fsize < 1<<31); GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[SceneEngine] Sending DIMS data - sizes: raw (%d)", buffer_len)); if (compress_dims) { dims_header |= GF_DIMS_UNIT_C; e = gf_gz_compress_payload(&buffer, buffer_len, &buffer_len); GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("/ compressed (%d)", buffer_len)); if (e) goto exit; } GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("\n")); /* Then, prepare the DIMS data using a bitstream instead of direct manipulation for endianness The new bitstream size should be: the size of the (compressed) data + 1 bytes for the header + 2 bytes for the size + 4 bytes if the size is greater than 65535 */ bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); if (buffer_len > 65535) { GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[SceneEngine] Warning: DIMS Unit size too big !!!\n")); gf_bs_write_u16(bs, 0); /* internal GPAC hack to indicate that the size is larger than 65535 */ gf_bs_write_u32(bs, buffer_len+1); } else { gf_bs_write_u16(bs, buffer_len+1); } gf_bs_write_u8(bs, dims_header); gf_bs_write_data(bs, buffer, buffer_len); gf_free(buffer); buffer = NULL; gf_bs_get_content(bs, data, size); gf_bs_del(bs); exit: if (!seng->dump_path) gf_free(cache_dir); if (buffer) gf_free(buffer); if (file) fclose(file); return e; }
static GF_Err gf_isom_get_3gpp_audio_esd(GF_SampleTableBox *stbl, GF_GenericAudioSampleEntryBox *entry, GF_ESD **out_esd) { GF_BitStream *bs; char szName[80]; (*out_esd) = gf_odf_desc_esd_new(2); (*out_esd)->decoderConfig->streamType = GF_STREAM_AUDIO; /*official mapping to MPEG-4*/ switch (entry->type) { case GF_ISOM_SUBTYPE_3GP_EVRC: (*out_esd)->decoderConfig->objectTypeIndication = GPAC_OTI_AUDIO_EVRC_VOICE; return GF_OK; case GF_ISOM_SUBTYPE_3GP_QCELP: { u32 block_size, sample_rate, sample_size, i; GF_SttsEntry *ent; /*only map CBR*/ sample_size = stbl->SampleSize->sampleSize; (*out_esd)->decoderConfig->objectTypeIndication = GPAC_OTI_AUDIO_13K_VOICE; bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); gf_bs_write_data(bs, "QLCMfmt ", 8); gf_bs_write_u32_le(bs, 150);/*fmt chunk size*/ gf_bs_write_u8(bs, 1); gf_bs_write_u8(bs, 0); /*QCELP GUID*/ gf_bs_write_data(bs, "\x41\x6D\x7F\x5E\x15\xB1\xD0\x11\xBA\x91\x00\x80\x5F\xB4\xB9\x7E", 16); gf_bs_write_u16_le(bs, 1); memset(szName, 0, 80); strcpy(szName, "QCELP-13K(GPAC-emulated)"); gf_bs_write_data(bs, szName, 80); ent = &stbl->TimeToSample->entries[0]; sample_rate = entry->samplerate_hi; block_size = ent ? ent->sampleDelta : 160; gf_bs_write_u16_le(bs, 8*sample_size*sample_rate/block_size); gf_bs_write_u16_le(bs, sample_size); gf_bs_write_u16_le(bs, block_size); gf_bs_write_u16_le(bs, sample_rate); gf_bs_write_u16_le(bs, entry->bitspersample); gf_bs_write_u32_le(bs, sample_size ? 0 : 7); /**/ for (i=0; i<7; i++) { static const u32 qcelp_r2s [] = {0, 1, 1, 4, 2, 8, 3, 17, 4, 35, 5, 8, 14, 1}; if (sample_size) { gf_bs_write_u16(bs, 0); } else { gf_bs_write_u8(bs, qcelp_r2s[2*i+1]); gf_bs_write_u8(bs, qcelp_r2s[2*i]); } } gf_bs_write_u16(bs, 0); memset(szName, 0, 80); gf_bs_write_data(bs, szName, 20);/*reserved*/ gf_bs_get_content(bs, & (*out_esd)->decoderConfig->decoderSpecificInfo->data, & (*out_esd)->decoderConfig->decoderSpecificInfo->dataLength); gf_bs_del(bs); } return GF_OK; case GF_ISOM_SUBTYPE_3GP_SMV: (*out_esd)->decoderConfig->objectTypeIndication = GPAC_OTI_AUDIO_SMV_VOICE; return GF_OK; default: break; } /*this is a user-reserved used in gpac - we need a std OTI for AMR/AMRWB*/ (*out_esd)->decoderConfig->objectTypeIndication = GPAC_OTI_MEDIA_GENERIC; bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); gf_bs_write_u32(bs, entry->type); gf_bs_write_u16(bs, entry->samplerate_hi); gf_bs_write_u16(bs, (entry->type == GF_ISOM_SUBTYPE_3GP_AMR) ? 160 : 320); gf_bs_write_u8(bs, entry->channel_count); gf_bs_write_u8(bs, entry->bitspersample); gf_bs_write_u8(bs, 0); gf_bs_get_content(bs, & (*out_esd)->decoderConfig->decoderSpecificInfo->data, & (*out_esd)->decoderConfig->decoderSpecificInfo->dataLength); gf_bs_del(bs); return GF_OK; }