/*special authoring functions*/ GF_EXPORT GF_BIFSConfig *gf_odf_get_bifs_config(GF_DefaultDescriptor *dsi, u8 oti) { Bool hasSize, cmd_stream; GF_BitStream *bs; GF_BIFSConfig *cfg; if (oti>=GPAC_OTI_SCENE_BIFS_EXTENDED) return NULL; if (!dsi || !dsi->data || !dsi->dataLength ) { /* Hack for T-DMB non compliant streams (OnTimeTek ?) */ cfg = (GF_BIFSConfig *) gf_odf_desc_new(GF_ODF_BIFS_CFG_TAG); cfg->pixelMetrics = 1; cfg->version = 1; return cfg; } bs = gf_bs_new(dsi->data, dsi->dataLength, GF_BITSTREAM_READ); cfg = (GF_BIFSConfig *) gf_odf_desc_new(GF_ODF_BIFS_CFG_TAG); if (oti==2) { /*3D Mesh Coding*/ gf_bs_read_int(bs, 1); /*PMF*/ gf_bs_read_int(bs, 1); } cfg->nodeIDbits = gf_bs_read_int(bs, 5); cfg->routeIDbits = gf_bs_read_int(bs, 5); if (oti==2) cfg->protoIDbits = gf_bs_read_int(bs, 5); cmd_stream = gf_bs_read_int(bs, 1); if (!cmd_stream) { cfg->elementaryMasks = gf_list_new(); while (1) { GF_ElementaryMask* em = (GF_ElementaryMask* ) gf_odf_New_ElemMask(); em->node_id = gf_bs_read_int(bs, cfg->nodeIDbits); gf_list_add(cfg->elementaryMasks, em); /*this assumes only FDP, BDP and IFS2D (no elem mask)*/ if (gf_bs_read_int(bs, 1) == 0) break; } gf_bs_align(bs); if (gf_bs_get_size(bs) != gf_bs_get_position(bs)) { GF_LOG(GF_LOG_WARNING, GF_LOG_CODEC, ("[ODF] Reading bifs config: shift in sizes (not supported)\n")); } } else { cfg->pixelMetrics = gf_bs_read_int(bs, 1); hasSize = gf_bs_read_int(bs, 1); if (hasSize) { cfg->pixelWidth = gf_bs_read_int(bs, 16); cfg->pixelHeight = gf_bs_read_int(bs, 16); } gf_bs_align(bs); if (gf_bs_get_size(bs) != gf_bs_get_position(bs)) GF_LOG(GF_LOG_WARNING, GF_LOG_CODEC, ("[ODF] Reading bifs config: shift in sizes (invalid descriptor)\n")); } gf_bs_del(bs); return cfg; }
/*allocates and writes the SL-PDU (Header + PDU) given the SLConfig and the GF_SLHeader for this PDU. AUs must be split in PDUs by another process if needed (packetizer).*/ GF_EXPORT void gf_sl_packetize(GF_SLConfig* slConfig, GF_SLHeader *Header, char *PDU, u32 size, char **outPacket, u32 *OutSize) { GF_BitStream *bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); *OutSize = 0; if (!bs) return; if (slConfig->useAccessUnitStartFlag) gf_bs_write_int(bs, Header->accessUnitStartFlag, 1); if (slConfig->useAccessUnitEndFlag) gf_bs_write_int(bs, Header->accessUnitEndFlag, 1); if (slConfig->OCRLength > 0) gf_bs_write_int(bs, Header->OCRflag, 1); if (slConfig->useIdleFlag) gf_bs_write_int(bs, Header->idleFlag, 1); if (slConfig->usePaddingFlag) { gf_bs_write_int(bs, Header->paddingFlag, 1); if (Header->paddingFlag) gf_bs_write_int(bs, Header->paddingBits, 3); } if (! Header->idleFlag && (! Header->paddingFlag || Header->paddingBits != 0)) { if (slConfig->packetSeqNumLength > 0) gf_bs_write_int(bs, Header->packetSequenceNumber, slConfig->packetSeqNumLength); if (slConfig->degradationPriorityLength > 0) { gf_bs_write_int(bs, Header->degradationPriorityFlag, 1); if (Header->degradationPriorityFlag) gf_bs_write_int(bs, Header->degradationPriority, slConfig->degradationPriorityLength); } if (Header->OCRflag) gf_bs_write_long_int(bs, Header->objectClockReference, slConfig->OCRLength); if (Header->accessUnitStartFlag) { if (slConfig->useRandomAccessPointFlag) gf_bs_write_int(bs, Header->randomAccessPointFlag, 1); if (slConfig->AUSeqNumLength > 0) gf_bs_write_int(bs, Header->AU_sequenceNumber, slConfig->AUSeqNumLength); if (slConfig->useTimestampsFlag) { gf_bs_write_int(bs, Header->decodingTimeStampFlag, 1); gf_bs_write_int(bs, Header->compositionTimeStampFlag, 1); } if (slConfig->instantBitrateLength > 0) gf_bs_write_int(bs, Header->instantBitrateFlag, 1); if (Header->decodingTimeStampFlag) gf_bs_write_long_int(bs, Header->decodingTimeStamp, slConfig->timestampLength); if (Header->compositionTimeStampFlag) gf_bs_write_long_int(bs, Header->compositionTimeStamp, slConfig->timestampLength); if (slConfig->AULength > 0) gf_bs_write_int(bs, Header->accessUnitLength, slConfig->AULength); if (Header->instantBitrateFlag) gf_bs_write_int(bs, Header->instantBitrate, slConfig->instantBitrateLength); } } //done with the Header, Alin gf_bs_align(bs); //write the PDU - already byte aligned with stuffing (paddingBits in SL Header) gf_bs_write_data(bs, PDU, size); gf_bs_align(bs); gf_bs_get_content(bs, outPacket, OutSize); gf_bs_del(bs); }
GF_Err gf_odf_read_esd_remove(GF_BitStream *bs, GF_ESDRemove *esdRem, u32 gf_odf_size_command) { u32 i = 0; if (!esdRem) return GF_BAD_PARAM; esdRem->ODID = gf_bs_read_int(bs, 10); /*aligned = */gf_bs_read_int(bs, 6); //aligned //we have gf_odf_size_command - 2 bytes left, and this is our ES_ID[1...255] //this works because OD commands are aligned if (gf_odf_size_command < 2) return GF_ODF_INVALID_DESCRIPTOR; if (gf_odf_size_command == 2) { esdRem->NbESDs = 0; esdRem->ES_ID = NULL; return GF_OK; } esdRem->NbESDs = (gf_odf_size_command - 2) / 2; esdRem->ES_ID = (u16 *)gf_malloc(sizeof(u16) * esdRem->NbESDs); if (!esdRem->ES_ID) return GF_OUT_OF_MEM; for (i = 0; i < esdRem->NbESDs; i++) { esdRem->ES_ID[i] = gf_bs_read_int(bs, 16); } //OD commands are aligned (but we should already be aligned.... /*nbBits = */gf_bs_align(bs); return GF_OK; }
u32 MPEGVS_OnData(struct __input_device * dr, const char* data) { GF_BitStream *bs; char *buf; u32 buf_size; float x, y, z; bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); sscanf(data, "%f;%f;%f;", &x, &y, &z); gf_bs_write_int(bs, 1, 1); gf_bs_write_float(bs, x); gf_bs_write_float(bs, y); gf_bs_write_float(bs, z); gf_bs_align(bs); gf_bs_get_content(bs, &buf, &buf_size); gf_bs_del(bs); dr->DispatchFrame(dr, (u8*)buf, buf_size); gf_free(buf); return GF_OK; }
GF_Err gf_odf_read_esd_update(GF_BitStream *bs, GF_ESDUpdate *esdUp, u32 gf_odf_size_command) { GF_Descriptor *tmp; u32 tmpSize = 0, nbBits = 0; GF_Err e = GF_OK; if (!esdUp) return GF_BAD_PARAM; esdUp->ODID = gf_bs_read_int(bs, 10); nbBits += 10; //very tricky, we're at the bit level here... while (1) { e = gf_odf_parse_descriptor(bs, &tmp, &tmpSize); if (e) return e; e = AddToESDUpdate(esdUp, tmp); if (e) return e; nbBits += (tmpSize + gf_odf_size_field_size(tmpSize)) * 8; //our com is aligned, so nbBits is between (gf_odf_size_command-1)*8 and gf_odf_size_command*8 if (((nbBits >(gf_odf_size_command - 1) * 8) && (nbBits <= gf_odf_size_command * 8)) || (nbBits > gf_odf_size_command * 8)) { //this one is a security break break; } } if (nbBits > gf_odf_size_command * 8) return GF_ODF_INVALID_COMMAND; //Align our bitstream nbBits += gf_bs_align(bs); if (nbBits != gf_odf_size_command * 8) return GF_ODF_INVALID_COMMAND; return e; }
GF_EXPORT GF_Err gf_oci_codec_encode(OCICodec *codec, char **outAU, u32 *au_length) { GF_BitStream *bs; u32 i, size, desc_size; GF_Err e; OCIEvent *ev; if (!codec || !codec->Mode || *outAU) return GF_BAD_PARAM; bs = NULL; size = 0; //get the size of each event i=0; while ((ev = (OCIEvent *)gf_list_enum(codec->OCIEvents, &i))) { //fixed size header size += 10; e = gf_odf_size_descriptor_list(codec->OCIEvents, &desc_size); if (e) goto err_exit; size += desc_size; } //encode bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); e = WriteSevenBitLength(bs, size); if (e) goto err_exit; //get one event, write it and delete it while (gf_list_count(codec->OCIEvents)) { ev = (OCIEvent *)gf_list_get(codec->OCIEvents, 0); gf_list_rem(codec->OCIEvents, 0); gf_bs_write_int(bs, ev->EventID, 15); gf_bs_write_int(bs, ev->AbsoluteTimeFlag, 1); gf_bs_write_data(bs, ev->StartingTime, 4); gf_bs_write_data(bs, ev->duration, 4); e = gf_odf_write_descriptor_list(bs, ev->OCIDescriptors); gf_oci_event_del(ev); if (e) goto err_exit; //OCI Event is aligned gf_bs_align(bs); } gf_bs_get_content(bs, outAU, au_length); gf_bs_del(bs); return GF_OK; err_exit: if (bs) gf_bs_del(bs); //delete everything while (gf_list_count(codec->OCIEvents)) { ev = (OCIEvent *)gf_list_get(codec->OCIEvents, 0); gf_list_rem(codec->OCIEvents, 0); gf_oci_event_del(ev); } return e; }
GF_EXPORT GF_Err gf_bifs_encode_au(GF_BifsEncoder *codec, u16 ESID, GF_List *command_list, char **out_data, u32 *out_data_length) { GF_BitStream *bs; GF_Err e; if (!codec || !command_list || !out_data || !out_data_length) return GF_BAD_PARAM; // gf_mx_p(codec->mx); codec->info = BE_GetStream(codec, ESID); if (!codec->info) { // gf_mx_v(codec->mx); return GF_BAD_PARAM; } bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); if (codec->info->config.elementaryMasks) { e = GF_NOT_SUPPORTED; } else { e = gf_bifs_enc_commands(codec, command_list, bs); } gf_bs_align(bs); gf_bs_get_content(bs, out_data, out_data_length); gf_bs_del(bs); // gf_mx_v(codec->mx); return e; }
u32 RunHTKDec(void *par) { GF_BitStream *bs; char *szWord; s32 word_index; u32 len, val, i; Float word_score; GF_SLHeader slh; GF_Codec *cod; unsigned char *buf; u32 buf_size; ISPriv *is_dec = (ISPriv *)par; // while (is_dec->htk_running) HTK_DoDetection(); szWord = HTK_GetWord(); word_index = HTK_GetWordIndex(); word_score = HTK_GetWordScore(); bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); /*HTK sensor buffer format: SFString - SFInt32 - SFFloat*/ gf_bs_write_int(bs, 1, 1); len = strlen(szWord); val = gf_get_bit_size(len); gf_bs_write_int(bs, val, 5); gf_bs_write_int(bs, len, val); for (i=0; i<len; i++) gf_bs_write_int(bs, szWord[i], 8); gf_bs_write_int(bs, 1, 1); gf_bs_write_int(bs, word_index, 32); gf_bs_write_int(bs, 1, 1); gf_bs_write_float(bs, word_score); gf_bs_align(bs); gf_bs_get_content(bs, &buf, &buf_size); gf_bs_del(bs); memset(&slh, 0, sizeof(GF_SLHeader)); slh.accessUnitStartFlag = slh.accessUnitEndFlag = 1; slh.compositionTimeStamp = 0; /*get all IS keySensor decoders and send frame*/ i=0; while ((cod = gf_list_enum(is_dec->scene->root_od->term->input_streams, &i))) { ISPriv *is = cod->decio->privateStack; if (is != is_dec) continue; if (is->type==IS_HTKSensor) { GF_Channel *ch = gf_list_get(cod->inChannels, 0); gf_es_receive_sl_packet(ch->service, ch, buf, buf_size, &slh, GF_OK); } } free(buf); is_dec->htk_running = 0; return 0; }
static GF_Err ParseConfig(GF_BitStream *bs, BIFSStreamInfo *info, u32 version) { Bool hasSize, cmd_stream; if (info->config.elementaryMasks) gf_list_del(info->config.elementaryMasks); info->config.elementaryMasks = NULL ; if (version==2) { info->config.Use3DMeshCoding = gf_bs_read_int(bs, 1); info->config.UsePredictiveMFField = gf_bs_read_int(bs, 1); } info->config.NodeIDBits = gf_bs_read_int(bs, 5); info->config.RouteIDBits = gf_bs_read_int(bs, 5); if (version==2) { info->config.ProtoIDBits = gf_bs_read_int(bs, 5); } cmd_stream = gf_bs_read_int(bs, 1); if (cmd_stream) { info->config.PixelMetrics = gf_bs_read_int(bs, 1); hasSize = gf_bs_read_int(bs, 1); if (hasSize) { info->config.Width = gf_bs_read_int(bs, 16); info->config.Height = gf_bs_read_int(bs, 16); } gf_bs_align(bs); if (gf_bs_get_size(bs) != gf_bs_get_position(bs)) return GF_ODF_INVALID_DESCRIPTOR; return GF_OK; } else { info->config.BAnimRAP = gf_bs_read_int(bs, 1); info->config.elementaryMasks = gf_list_new(); while (1) { /*u32 node_id = */gf_bs_read_int(bs, info->config.NodeIDBits); /*this assumes only FDP, BDP and IFS2D (no elem mask)*/ if (gf_bs_read_int(bs, 1) == 0) break; } gf_bs_align(bs); if (gf_bs_get_size(bs) != gf_bs_get_position(bs)) return GF_NOT_SUPPORTED; return GF_OK; } }
GF_EXPORT GF_Err gf_bifs_encoder_get_config(GF_BifsEncoder *codec, u16 ESID, char **out_data, u32 *out_data_length) { GF_BitStream *bs; if (!codec || !out_data || !out_data_length) return GF_BAD_PARAM; // gf_mx_p(codec->mx); codec->info = BE_GetStream(codec, ESID); if (!codec->info) { // gf_mx_v(codec->mx); return GF_BAD_PARAM; } bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); if (codec->info->config.version==2) { gf_bs_write_int(bs, codec->info->config.Use3DMeshCoding ? 1 : 0, 1); gf_bs_write_int(bs, codec->info->config.UsePredictiveMFField ? 1 : 0, 1); } gf_bs_write_int(bs, codec->info->config.NodeIDBits, 5); gf_bs_write_int(bs, codec->info->config.RouteIDBits, 5); if (codec->info->config.version==2) { gf_bs_write_int(bs, codec->info->config.ProtoIDBits, 5); } if (codec->info->config.elementaryMasks) { u32 i, count; gf_bs_write_int(bs, 0, 1); gf_bs_write_int(bs, codec->info->config.BAnimRAP, 1); count = gf_list_count(codec->info->config.elementaryMasks); for (i=0; i<count; i++) { BIFSElementaryMask *em = (BIFSElementaryMask *)gf_list_get(codec->info->config.elementaryMasks, i); if (em->node) gf_bs_write_int(bs, gf_node_get_id((GF_Node*)em->node), codec->info->config.NodeIDBits); else gf_bs_write_int(bs, em->node_id, codec->info->config.NodeIDBits); gf_bs_write_int(bs, (i+1==count) ? 0 : 1, 1); } } else { gf_bs_write_int(bs, 1, 1); gf_bs_write_int(bs, codec->info->config.PixelMetrics ? 1 : 0, 1); if (codec->info->config.Width || codec->info->config.Height) { gf_bs_write_int(bs, 1, 1); gf_bs_write_int(bs, codec->info->config.Width, 16); gf_bs_write_int(bs, codec->info->config.Height, 16); } else { gf_bs_write_int(bs, 0, 1); } } gf_bs_align(bs); gf_bs_get_content(bs, out_data, out_data_length); gf_bs_del(bs); // gf_mx_v(codec->mx); return GF_OK; }
static GF_ESD *AAC_GetESD(AACReader *read) { GF_BitStream *dsi; GF_ESD *esd; u32 i, sbr_sr_idx; esd = gf_odf_desc_esd_new(0); esd->decoderConfig->streamType = GF_STREAM_AUDIO; esd->decoderConfig->objectTypeIndication = read->oti; esd->ESID = 1; esd->OCRESID = 1; esd->slConfig->timestampResolution = read->sample_rate; if (read->is_live) esd->slConfig->useAccessUnitEndFlag = esd->slConfig->useAccessUnitStartFlag = 1; dsi = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); /*write as regular AAC*/ gf_bs_write_int(dsi, read->prof, 5); gf_bs_write_int(dsi, read->sr_idx, 4); gf_bs_write_int(dsi, read->nb_ch, 4); gf_bs_align(dsi); /*always signal implicit S BR in case it's used*/ sbr_sr_idx = read->sr_idx; for (i=0; i<16; i++) { if (GF_M4ASampleRates[i] == (u32) 2*read->sample_rate) { sbr_sr_idx = i; break; } } gf_bs_write_int(dsi, 0x2b7, 11); gf_bs_write_int(dsi, 5, 5); gf_bs_write_int(dsi, 1, 1); gf_bs_write_int(dsi, sbr_sr_idx, 4); gf_bs_align(dsi); gf_bs_get_content(dsi, &esd->decoderConfig->decoderSpecificInfo->data, &esd->decoderConfig->decoderSpecificInfo->dataLength); gf_bs_del(dsi); return esd; }
GF_EXPORT void gf_sl_depacketize (GF_SLConfig *slConfig, GF_SLHeader *Header, char *PDU, u32 PDULength, u32 *HeaderLen) { GF_BitStream *bs; *HeaderLen = 0; if (!Header) return; //reset the input header memset(Header, 0, sizeof(GF_SLHeader)); bs = gf_bs_new(PDU, PDULength, GF_BITSTREAM_READ); if (!bs) return; if (slConfig->useAccessUnitStartFlag) Header->accessUnitStartFlag = gf_bs_read_int(bs, 1); if (slConfig->useAccessUnitEndFlag) Header->accessUnitEndFlag = gf_bs_read_int(bs, 1); if ( !slConfig->useAccessUnitStartFlag && !slConfig->useAccessUnitEndFlag) { Header->accessUnitStartFlag = 1; Header->accessUnitEndFlag = 1; } if (slConfig->OCRLength > 0) Header->OCRflag = gf_bs_read_int(bs, 1); if (slConfig->useIdleFlag) Header->idleFlag = gf_bs_read_int(bs, 1); if (slConfig->usePaddingFlag) { Header->paddingFlag = gf_bs_read_int(bs, 1); if (Header->paddingFlag) Header->paddingBits = gf_bs_read_int(bs, 3); } if (!Header->idleFlag && (!Header->paddingFlag || Header->paddingBits != 0)) { if (slConfig->packetSeqNumLength > 0) Header->packetSequenceNumber = gf_bs_read_int(bs, slConfig->packetSeqNumLength); if (slConfig->degradationPriorityLength > 0) { Header->degradationPriorityFlag = gf_bs_read_int(bs, 1); if (Header->degradationPriorityFlag) Header->degradationPriority = gf_bs_read_int(bs, slConfig->degradationPriorityLength); } if (Header->OCRflag) Header->objectClockReference = gf_bs_read_int(bs, slConfig->OCRLength); if (Header->accessUnitStartFlag) { if (slConfig->useRandomAccessPointFlag) Header->randomAccessPointFlag = gf_bs_read_int(bs, 1); if (slConfig->AUSeqNumLength > 0) Header->AU_sequenceNumber = gf_bs_read_int(bs, slConfig->AUSeqNumLength); if (slConfig->useTimestampsFlag) { Header->decodingTimeStampFlag = gf_bs_read_int(bs, 1); Header->compositionTimeStampFlag = gf_bs_read_int(bs, 1); } if (slConfig->instantBitrateLength > 0) Header->instantBitrateFlag = gf_bs_read_int(bs, 1); if (Header->decodingTimeStampFlag) Header->decodingTimeStamp = gf_bs_read_long_int(bs, slConfig->timestampLength); if (Header->compositionTimeStampFlag) Header->compositionTimeStamp = gf_bs_read_long_int(bs, slConfig->timestampLength); if (slConfig->AULength > 0) Header->accessUnitLength = gf_bs_read_int(bs, slConfig->AULength); if (Header->instantBitrateFlag) Header->instantBitrate = gf_bs_read_int(bs, slConfig->instantBitrateLength); } } gf_bs_align(bs); *HeaderLen = (u32) gf_bs_get_position(bs); gf_bs_del(bs); }
GF_Err gf_odf_write_ipmp_remove(GF_BitStream *bs, GF_IPMPRemove *ipmpRem) { GF_Err e; u32 size, i; if (!ipmpRem) return GF_BAD_PARAM; e = gf_odf_size_ipmp_remove(ipmpRem, &size); if (e) return e; e = gf_odf_write_base_descriptor(bs, ipmpRem->tag, size); if (e) return e; for (i = 0; i < ipmpRem->NbIPMPDs; i++) { gf_bs_write_int(bs, ipmpRem->IPMPDescID[i], 8); } //OD commands are aligned gf_bs_align(bs); return GF_OK; }
GF_Err gf_odf_write_od_remove(GF_BitStream *bs, GF_ODRemove *odRem) { GF_Err e; u32 size, i; if (!odRem) return GF_BAD_PARAM; e = gf_odf_size_od_remove(odRem, &size); if (e) return e; e = gf_odf_write_base_descriptor(bs, odRem->tag, size); if (e) return e; for (i = 0; i < odRem->NbODs; i++) { gf_bs_write_int(bs, odRem->OD_ID[i], 10); } //OD commands are aligned gf_bs_align(bs); return GF_OK; }
GF_Err gf_odf_read_od_remove(GF_BitStream *bs, GF_ODRemove *odRem, u32 gf_odf_size_command) { u32 i = 0, nbBits; if (!odRem) return GF_BAD_PARAM; odRem->NbODs = (u32)(gf_odf_size_command * 8) / 10; odRem->OD_ID = (u16 *)gf_malloc(sizeof(u16) * odRem->NbODs); if (!odRem->OD_ID) return GF_OUT_OF_MEM; for (i = 0; i < odRem->NbODs; i++) { odRem->OD_ID[i] = gf_bs_read_int(bs, 10); } nbBits = odRem->NbODs * 10; //now we need to align !!! nbBits += gf_bs_align(bs); if (nbBits != (gf_odf_size_command * 8)) return GF_ODF_INVALID_COMMAND; return GF_OK; }
GF_Err gf_odf_read_ipmp_update(GF_BitStream *bs, GF_IPMPUpdate *ipmpUp, u32 gf_odf_size_command) { GF_Descriptor *tmp; u32 tmpSize = 0, nbBytes = 0; GF_Err e = GF_OK; if (!ipmpUp) return GF_BAD_PARAM; while (nbBytes < gf_odf_size_command) { e = gf_odf_parse_descriptor(bs, &tmp, &tmpSize); if (e) return e; e = AddToIPMPDUpdate(ipmpUp, tmp); if (e) return e; nbBytes += tmpSize + gf_odf_size_field_size(tmpSize); } //OD commands are aligned gf_bs_align(bs); if (nbBytes != gf_odf_size_command) return GF_ODF_INVALID_COMMAND; return e; }
GF_EXPORT GF_Err gf_odf_codec_encode(GF_ODCodec *codec, u32 cleanup_type) { GF_ODCom *com; GF_Err e = GF_OK; u32 i; if (!codec) return GF_BAD_PARAM; //check our bitstream: if existing, this means the previous encoded AU was not retrieved //we DON'T allow that if (codec->bs) return GF_BAD_PARAM; codec->bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); if (!codec->bs) return GF_OUT_OF_MEM; /*encode each command*/ i = 0; while ((com = (GF_ODCom *)gf_list_enum(codec->CommandList, &i))) { e = gf_odf_write_command(codec->bs, com); if (e) goto err_exit; //don't forget OD Commands are aligned... gf_bs_align(codec->bs); } //if an error occurs, delete the GF_BitStream and empty the codec err_exit: if (e) { gf_bs_del(codec->bs); codec->bs = NULL; } if (cleanup_type == 1) { while (gf_list_count(codec->CommandList)) { com = (GF_ODCom *)gf_list_get(codec->CommandList, 0); gf_odf_delete_command(com); gf_list_rem(codec->CommandList, 0); } } if (cleanup_type == 0) { gf_list_reset(codec->CommandList); } return e; }
GF_Err gf_odf_write_esd_remove(GF_BitStream *bs, GF_ESDRemove *esdRem) { GF_Err e; u32 size, i; if (!esdRem) return GF_BAD_PARAM; e = gf_odf_size_esd_remove(esdRem, &size); if (e) return e; e = gf_odf_write_base_descriptor(bs, esdRem->tag, size); if (e) return e; gf_bs_write_int(bs, esdRem->ODID, 10); gf_bs_write_int(bs, 0, 6); //aligned for (i = 0; i < esdRem->NbESDs; i++) { gf_bs_write_int(bs, esdRem->ES_ID[i], 16); } //OD commands are aligned (but we are already aligned.... gf_bs_align(bs); return GF_OK; }
GF_Err gf_odf_read_ipmp_remove(GF_BitStream *bs, GF_IPMPRemove *ipmpRem, u32 gf_odf_size_command) { u32 i; if (!ipmpRem) return GF_BAD_PARAM; //we have gf_odf_size_command bytes left, and this is our IPMPD_ID[1...255] //this works because OD commands are aligned if (!gf_odf_size_command) return GF_OK; ipmpRem->NbIPMPDs = gf_odf_size_command; ipmpRem->IPMPDescID = (u8 *)gf_malloc(sizeof(u8) * ipmpRem->NbIPMPDs); if (!ipmpRem->IPMPDescID) return GF_OUT_OF_MEM; for (i = 0; i < ipmpRem->NbIPMPDs; i++) { ipmpRem->IPMPDescID[i] = gf_bs_read_int(bs, 8); } //OD commands are aligned gf_bs_align(bs); return GF_OK; }
GF_Err gf_odf_write_od_update(GF_BitStream *bs, GF_ODUpdate *odUp) { GF_Err e; GF_Descriptor *tmp; u32 size, i; if (!odUp) return GF_BAD_PARAM; e = gf_odf_size_od_update(odUp, &size); if (e) return e; gf_odf_write_base_descriptor(bs, odUp->tag, size); if (e) return e; i = 0; while ((tmp = (GF_Descriptor *)gf_list_enum(odUp->objectDescriptors, &i))) { e = gf_odf_write_descriptor(bs, tmp); if (e) return e; } //OD commands are aligned gf_bs_align(bs); return GF_OK; }
GF_Err gf_odf_write_ipmp_update(GF_BitStream *bs, GF_IPMPUpdate *ipmpUp) { GF_Err e; GF_Descriptor *tmp; u32 size, i; if (!ipmpUp) return GF_BAD_PARAM; e = gf_odf_size_ipmp_update(ipmpUp, &size); if (e) return e; e = gf_odf_write_base_descriptor(bs, ipmpUp->tag, size); if (e) return e; i = 0; while ((tmp = (GF_Descriptor *)gf_list_enum(ipmpUp->IPMPDescList, &i))) { e = gf_odf_write_descriptor(bs, tmp); if (e) return e; } //OD commands are aligned gf_bs_align(bs); return GF_OK; }
GF_EXPORT GF_Err gf_odf_codec_decode(GF_ODCodec *codec) { GF_Err e = GF_OK; u32 size = 0, comSize, bufSize; GF_ODCom *com; if (!codec || !codec->bs) return GF_BAD_PARAM; bufSize = (u32)gf_bs_available(codec->bs); while (size < bufSize) { e = gf_odf_parse_command(codec->bs, &com, &comSize); if (e) goto err_exit; gf_list_add(codec->CommandList, com); size += comSize + gf_odf_size_field_size(comSize); //OD Commands are aligned gf_bs_align(codec->bs); } //then delete our bitstream gf_bs_del(codec->bs); codec->bs = NULL; if (size != bufSize) { e = GF_ODF_INVALID_COMMAND; goto err_exit; } return e; err_exit: if (codec->bs) { gf_bs_del(codec->bs); codec->bs = NULL; } while (gf_list_count(codec->CommandList)) { com = (GF_ODCom*)gf_list_get(codec->CommandList, 0); gf_odf_delete_command(com); gf_list_rem(codec->CommandList, 0); } return e; }
GF_Err gf_odf_write_esd_update(GF_BitStream *bs, GF_ESDUpdate *esdUp) { GF_Descriptor *tmp; GF_Err e; u32 size, i; if (!esdUp) return GF_BAD_PARAM; e = gf_odf_size_esd_update(esdUp, &size); if (e) return e; e = gf_odf_write_base_descriptor(bs, esdUp->tag, size); if (e) return e; gf_bs_write_int(bs, esdUp->ODID, 10); i = 0; while ((tmp = (GF_Descriptor *)gf_list_enum(esdUp->ESDescriptors, &i))) { e = gf_odf_write_descriptor(bs, tmp); if (e) return e; } //OD commands are aligned gf_bs_align(bs); return GF_OK; }
static void DEV_Start(struct __input_device *ifce) { GF_BitStream *bs; char *buf, *szWord; u32 len, val, i, buf_size; szWord = "Hello InputSensor!"; bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); /*HTK sensor buffer format: SFString - SFInt32 - SFFloat*/ gf_bs_write_int(bs, 1, 1); len = strlen(szWord); val = gf_get_bit_size(len); gf_bs_write_int(bs, val, 5); gf_bs_write_int(bs, len, val); for (i=0; i<len; i++) gf_bs_write_int(bs, szWord[i], 8); gf_bs_align(bs); gf_bs_get_content(bs, &buf, &buf_size); gf_bs_del(bs); ifce->DispatchFrame(ifce, buf, buf_size); gf_free(buf); }
u32 MPEGVS_OnData(struct __input_device * dr, const char* data) { GF_BitStream *bs; char *buf; u32 buf_size; float x, y, z, q, a, b; MPEGVSCTX; bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); if ( rc->sensorAndroidType == 1 || rc->sensorAndroidType == 2 || rc->sensorAndroidType == 3 || rc->sensorAndroidType == 4 ) { sscanf(data, "%f;%f;%f;", &x, &y, &z); gf_bs_write_int(bs, 1, 1); gf_bs_write_float(bs, x); gf_bs_write_float(bs, y); gf_bs_write_float(bs, z); } else if ( rc->sensorAndroidType == 5 || rc->sensorAndroidType == 6 ) { sscanf(data, "%f;", &x); gf_bs_write_int(bs, 1, 1); gf_bs_write_float(bs, x); } else if ( rc->sensorAndroidType == 11 ) { sscanf(data, "%f;%f;%f;", &x, &y, &z); gf_bs_write_int(bs, 1, 1); gf_bs_write_float(bs, x); gf_bs_write_float(bs, y); gf_bs_write_float(bs, z); /*gf_bs_write_float(bs, q);*/ } else if ( rc->sensorAndroidType == 100 ) { sscanf(data, "%f;%f;%f;%f;%f;", &x, &y, &z, &a, &b); gf_bs_write_int(bs, 1, 1); gf_bs_write_float(bs, x); gf_bs_write_float(bs, y); gf_bs_write_float(bs, z); gf_bs_write_int(bs, 1, 1); gf_bs_write_float(bs, a); gf_bs_write_int(bs, 1, 1); gf_bs_write_float(bs, b); /*gf_bs_write_float(bs, q);*/ } gf_bs_align(bs); gf_bs_get_content(bs, &buf, &buf_size); gf_bs_del(bs); dr->DispatchFrame(dr, (u8*)buf, buf_size); gf_free(buf); return GF_OK; }
GF_Err gp_rtp_builder_do_mpeg4(GP_RTPPacketizer *builder, char *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize) { char *sl_buffer, *payl_buffer; u32 sl_buffer_size, payl_buffer_size; u32 auh_size_tmp, bytesLeftInPacket, infoSize, pckSize; u64 pos; u8 flush_pck, no_split; flush_pck = 0; bytesLeftInPacket = data_size; /*flush everything*/ if (!data) { if (builder->payload) goto flush_packet; return GF_OK; } if (builder->payload && builder->force_flush) goto flush_packet; //go till done while (bytesLeftInPacket) { no_split = 0; if (builder->sl_header.accessUnitStartFlag) { //init SL if (builder->sl_header.compositionTimeStamp != builder->sl_header.decodingTimeStamp) { builder->sl_header.decodingTimeStampFlag = 1; } builder->sl_header.compositionTimeStampFlag = 1; builder->sl_header.accessUnitLength = FullAUSize; //init some vars - based on the available size and the TS //we decide if we go with the same RTP TS serie or not if (builder->payload) { //don't store more than what we can (that is 2^slMap->CTSDelta - 1) if ( (builder->flags & GP_RTP_PCK_SIGNAL_TS) && (builder->sl_header.compositionTimeStamp - builder->rtp_header.TimeStamp >= (u32) ( 1 << builder->slMap.CTSDeltaLength) ) ) { goto flush_packet; } //don't split AU if # TS , start a new RTP pck if (builder->sl_header.compositionTimeStamp != builder->rtp_header.TimeStamp) no_split = 1; } } /*new RTP Packet*/ if (!builder->payload) { /*first SL in RTP*/ builder->first_sl_in_rtp = 1; /*if this is the end of an AU we will set it to 0 as soon as an AU is splited*/ builder->rtp_header.Marker = 1; builder->rtp_header.PayloadType = builder->PayloadType; builder->rtp_header.SequenceNumber += 1; builder->rtp_header.TimeStamp = (u32) builder->sl_header.compositionTimeStamp; /*prepare the mapped headers*/ builder->pck_hdr = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); builder->payload = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); pckSize = infoSize = 0; builder->bytesInPacket = 0; /*in multiSL there is a MSLHSize structure on 2 bytes*/ builder->auh_size = 0; if (builder->has_AU_header) { builder->auh_size = 16; gf_bs_write_int(builder->pck_hdr, 0, 16); } flush_pck = 0; /*and create packet*/ builder->OnNewPacket(builder->cbk_obj, &builder->rtp_header); } //make sure we are not interleaving too much - this should never happen actually if (builder->slMap.IndexDeltaLength && !builder->first_sl_in_rtp && (builder->sl_header.AU_sequenceNumber - builder->last_au_sn >= (u32) 1<<builder->slMap.IndexDeltaLength)) { //we cannot write this packet here goto flush_packet; } /*check max ptime*/ if (builder->max_ptime && ( (u32) builder->sl_header.compositionTimeStamp >= builder->rtp_header.TimeStamp + builder->max_ptime) ) goto flush_packet; auh_size_tmp = gf_rtp_build_au_hdr_size(builder, &builder->sl_header); infoSize = auh_size_tmp + builder->auh_size; infoSize /= 8; /*align*/ if ( (builder->auh_size + auh_size_tmp) % 8) infoSize += 1; if (bytesLeftInPacket + infoSize + builder->bytesInPacket <= builder->Path_MTU) { //End of our data chunk pckSize = bytesLeftInPacket; builder->sl_header.accessUnitEndFlag = IsAUEnd; builder->auh_size += auh_size_tmp; builder->sl_header.paddingFlag = builder->sl_header.paddingBits ? 1 : 0; } else { //AU cannot fit in packet. If no split, start a new packet if (no_split) goto flush_packet; builder->auh_size += auh_size_tmp; pckSize = builder->Path_MTU - (infoSize + builder->bytesInPacket); //that's the end of the rtp packet flush_pck = 1; //but not of the AU -> marker is 0 builder->rtp_header.Marker = 0; } gf_rtp_build_au_hdr_write(builder, pckSize, builder->rtp_header.TimeStamp); //notify the user of our data structure if (builder->OnDataReference) builder->OnDataReference(builder->cbk_obj, pckSize, data_size - bytesLeftInPacket); else gf_bs_write_data(builder->payload, data + (data_size - bytesLeftInPacket), pckSize); bytesLeftInPacket -= pckSize; builder->bytesInPacket += pckSize; /*update IV*/ builder->IV += pckSize; builder->sl_header.paddingFlag = 0; builder->sl_header.accessUnitStartFlag = 0; //we are splitting a payload, auto increment SL seq num if (bytesLeftInPacket) { builder->sl_header.packetSequenceNumber += 1; } else if (! (builder->flags & GP_RTP_PCK_USE_MULTI) ) { builder->rtp_header.Marker = 1; flush_pck = 1; } //first SL in RTP is done builder->first_sl_in_rtp = 0; //store current sl builder->last_au_sn = builder->sl_header.AU_sequenceNumber; if (!flush_pck) continue; //done with the packet flush_packet: gf_bs_align(builder->pck_hdr); /*no aux data yet*/ if (builder->slMap.AuxiliaryDataSizeLength) { //write RSLH after the MSLH gf_bs_write_int(builder->pck_hdr, 0, builder->slMap.AuxiliaryDataSizeLength); } /*rewrite the size header*/ if (builder->has_AU_header) { pos = gf_bs_get_position(builder->pck_hdr); gf_bs_seek(builder->pck_hdr, 0); builder->auh_size -= 16; gf_bs_write_int(builder->pck_hdr, builder->auh_size, 16); gf_bs_seek(builder->pck_hdr, pos); } sl_buffer = NULL; gf_bs_get_content(builder->pck_hdr, &sl_buffer, &sl_buffer_size); //delete our bitstream gf_bs_del(builder->pck_hdr); builder->pck_hdr = NULL; payl_buffer = NULL; payl_buffer_size = 0; if (!builder->OnDataReference) gf_bs_get_content(builder->payload, &payl_buffer, &payl_buffer_size); gf_bs_del(builder->payload); builder->payload = NULL; /*notify header*/ builder->OnData(builder->cbk_obj, sl_buffer, sl_buffer_size, 1); /*notify payload*/ if (payl_buffer) { builder->OnData(builder->cbk_obj, payl_buffer, payl_buffer_size, 0); gf_free(payl_buffer); } /*flush packet*/ builder->OnPacketDone(builder->cbk_obj, &builder->rtp_header); gf_free(sl_buffer); } //packet is done, update AU markers if (IsAUEnd) { builder->sl_header.accessUnitStartFlag = 1; builder->sl_header.accessUnitEndFlag = 0; } return GF_OK; }
void detect_and_draw_objects(GF_InputSensorDevice *ifce, IplImage* image, CvHaarClassifierCascade* cascade, int do_pyramids ) { IplImage* small_image = image; CvMemStorage* storage = cvCreateMemStorage(0); CvSeq* faces; int i, scale = 1; //CvRect* theRealFace; int theRealX=0, theRealY=0, theRealHeight=0 , theRealWidth=0; int tmpMaxSurface=0; if( do_pyramids ) { small_image = cvCreateImage( cvSize(image->width/2,image->height/2), IPL_DEPTH_8U, 3 ); cvPyrDown( image, small_image, CV_GAUSSIAN_5x5 ); scale = 2; } faces = cvHaarDetectObjects( small_image, cascade, storage, 1.2, 2, CV_HAAR_DO_CANNY_PRUNING, cvSize(0,0) ); for( i = 0; i < faces->total; i++ ) { CvRect face_rect = *(CvRect*)cvGetSeqElem( faces, i ); /* cvRectangle( image, cvPoint(face_rect.x*scale,face_rect.y*scale), cvPoint((face_rect.x+face_rect.width)*scale, (face_rect.y+face_rect.height)*scale), CV_RGB(0,255,0), 3 );*/ if(face_rect.width*face_rect.height>tmpMaxSurface) { theRealX=face_rect.x; theRealY=face_rect.y; theRealHeight=face_rect.height; theRealWidth=face_rect.width; tmpMaxSurface=face_rect.width*face_rect.height; } } cvRectangle( image, cvPoint(theRealX*scale,theRealY*scale), cvPoint((theRealX+theRealWidth)*scale, (theRealY+theRealHeight)*scale), CV_RGB(0,255,0), 3, 8, 0 ); GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[OpenCV] translation selon X : %d - translation selon Y : %d\n", (theRealX - prev_x0), (theRealY -prev_y0) )); /*send data frame to GPAC*/ { char *buf; u32 buf_size; GF_BitStream *bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); gf_bs_write_int(bs, 1, 1); gf_bs_write_float(bs, (Float) (theRealX - 640/2) ); gf_bs_write_float(bs, (Float) (480/2 - theRealY) ); gf_bs_align(bs); gf_bs_get_content(bs, &buf, &buf_size); gf_bs_del(bs); ifce->DispatchFrame(ifce, buf, buf_size); gf_free(buf); } prev_x0=theRealX; prev_y0=theRealY; if( small_image != image ) cvReleaseImage( &small_image ); cvReleaseMemStorage( &storage ); }
void gf_term_string_input(GF_Terminal *term, u32 character) { u32 i; GF_BitStream *bs; GF_SLHeader slh; #ifndef GPAC_DISABLE_X3D X_StringSensor *n; #endif GF_Codec *cod; char *buf; u32 buf_size; if (!character || !term) return; if (!gf_list_count(term->input_streams) && !gf_list_count(term->x3d_sensors)) return; memset(&slh, 0, sizeof(GF_SLHeader)); slh.accessUnitStartFlag = slh.accessUnitEndFlag = 1; slh.compositionTimeStampFlag = 1; /*cf above*/ slh.compositionTimeStamp = 0; /*get all IS StringSensor decoders and send frame*/ i=0; while ((cod = (GF_Codec*)gf_list_enum(term->input_streams, &i))) { ISPriv *is = (ISPriv *)cod->decio->privateStack; if (is->type==IS_StringSensor) { // GF_Channel *ch = (GF_Channel *)gf_list_get(cod->inChannels, 0); is->enteredText[is->text_len] = character; is->text_len += 1; /*write empty DDF*/ bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); gf_bs_write_int(bs, 0, 1); gf_bs_write_int(bs, 0, 1); gf_bs_align(bs); gf_bs_get_content(bs, &buf, &buf_size); gf_bs_del(bs); // gf_es_receive_sl_packet(ch->service, ch, buf, buf_size, &slh, GF_OK); IS_ProcessData((GF_SceneDecoder*)cod->decio, buf, buf_size, 0, 0, 0); gf_free(buf); } } #ifndef GPAC_DISABLE_X3D /*get all X3D StringSensors*/ i=0; while ((n = (X_StringSensor*)gf_list_enum(term->x3d_sensors, &i))) { StringSensorStack *st; char szStr[5000]; const unsigned short *ptr; u32 len; if (gf_node_get_tag((GF_Node*)n) != TAG_X3D_StringSensor) continue; if (!n->enabled) continue; st = (StringSensorStack *) gf_node_get_private((GF_Node *)n); if (character=='\b') { if (n->deletionAllowed && st->text_len) { st->text_len -= 1; st->enteredText[st->text_len] = 0; ptr = st->enteredText; len = gf_utf8_wcstombs(szStr, 10, &ptr); if (n->enteredText.buffer) gf_free(n->enteredText.buffer); szStr[len] = 0; n->enteredText.buffer = gf_strdup(szStr); gf_node_event_out_str((GF_Node *)n, "enteredText"); } } else if (character=='\r') { if (n->finalText.buffer) gf_free(n->finalText.buffer); n->finalText.buffer = n->enteredText.buffer; n->enteredText.buffer = gf_strdup(""); st->text_len = 0; gf_node_event_out_str((GF_Node *)n, "enteredText"); gf_node_event_out_str((GF_Node *)n, "finalText"); } else { st->enteredText[st->text_len] = character; st->text_len += 1; st->enteredText[st->text_len] = 0; ptr = st->enteredText; len = gf_utf8_wcstombs(szStr, 10, &ptr); if (n->enteredText.buffer) gf_free(n->enteredText.buffer); szStr[len] = 0; n->enteredText.buffer = gf_strdup(szStr); gf_node_event_out_str((GF_Node *)n, "enteredText"); } } #endif }
Bool gf_term_keyboard_input(GF_Terminal *term, u32 key_code, u32 hw_code, Bool isKeyUp) { u32 i; GF_BitStream *bs; GF_SLHeader slh; char *buf; #ifndef GPAC_DISABLE_X3D X_KeySensor *n; #endif u32 buf_size; u32 actionKey = 0; u32 shiftKeyDown, controlKeyDown, altKeyDown; GF_Codec *cod; s32 keyPressed, keyReleased, actionKeyPressed, actionKeyReleased; if (!term || (!gf_list_count(term->input_streams) && !gf_list_count(term->x3d_sensors)) ) return 0; memset(&slh, 0, sizeof(GF_SLHeader)); slh.accessUnitStartFlag = slh.accessUnitEndFlag = 1; slh.compositionTimeStampFlag = 1; /*cf above*/ slh.compositionTimeStamp = 0; bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); shiftKeyDown = controlKeyDown = altKeyDown = 0; keyPressed = keyReleased = actionKeyPressed = actionKeyReleased = 0; /*key-sensor codes*/ switch (key_code) { case GF_KEY_F1: actionKey = 1; break; case GF_KEY_F2: actionKey = 2; break; case GF_KEY_F3: actionKey = 3; break; case GF_KEY_F4: actionKey = 4; break; case GF_KEY_F5: actionKey = 5; break; case GF_KEY_F6: actionKey = 6; break; case GF_KEY_F7: actionKey = 7; break; case GF_KEY_F8: actionKey = 8; break; case GF_KEY_F9: actionKey = 9; break; case GF_KEY_F10: actionKey = 10; break; case GF_KEY_F11: actionKey = 11; break; case GF_KEY_F12: actionKey = 12; break; case GF_KEY_HOME: actionKey = 13; break; case GF_KEY_END: actionKey = 14; break; case GF_KEY_PAGEUP: actionKey = 15; break; case GF_KEY_PAGEDOWN: actionKey = 16; break; case GF_KEY_UP: actionKey = 17; break; case GF_KEY_DOWN: actionKey = 18; break; case GF_KEY_LEFT: actionKey = 19; break; case GF_KEY_RIGHT: actionKey = 20; break; case GF_KEY_SHIFT: actionKey = 0; shiftKeyDown = isKeyUp ? 1 : 2; break; case GF_KEY_CONTROL: actionKey = 0; controlKeyDown = isKeyUp ? 1 : 2; break; case GF_KEY_ALT: actionKey = 0; altKeyDown = isKeyUp ? 1 : 2; break; default: actionKey = 0; break; } if (actionKey) { if (isKeyUp) actionKeyReleased = actionKey; else actionKeyPressed = actionKey; } else { /*handle numeric pad*/ if ((key_code>=GF_KEY_0) && (key_code<=GF_KEY_9) ) { key_code = key_code + 0x30 - GF_KEY_0; } else key_code = hw_code; if (isKeyUp) keyReleased = key_code; else keyPressed = key_code; } gf_bs_write_int(bs, keyPressed ? 1 : 0, 1); if (keyPressed) gf_bs_write_int(bs, keyPressed, 32); gf_bs_write_int(bs, keyReleased ? 1 : 0, 1); if (keyReleased) gf_bs_write_int(bs, keyReleased, 32); gf_bs_write_int(bs, actionKeyPressed ? 1 : 0, 1); if (actionKeyPressed) gf_bs_write_int(bs, actionKeyPressed, 32); gf_bs_write_int(bs, actionKeyReleased ? 1 : 0, 1); if (actionKeyReleased) gf_bs_write_int(bs, actionKeyReleased, 32); gf_bs_write_int(bs, shiftKeyDown ? 1 : 0 , 1); if (shiftKeyDown) gf_bs_write_int(bs, shiftKeyDown-1, 1); gf_bs_write_int(bs, controlKeyDown ? 1 : 0 , 1); if (controlKeyDown) gf_bs_write_int(bs, controlKeyDown-1, 1); gf_bs_write_int(bs, altKeyDown ? 1 : 0 , 1); if (altKeyDown) gf_bs_write_int(bs, altKeyDown, 1); gf_bs_align(bs); gf_bs_get_content(bs, &buf, &buf_size); gf_bs_del(bs); /*get all IS keySensor decoders and send frame*/ i=0; while ((cod = (GF_Codec*)gf_list_enum(term->input_streams, &i))) { ISPriv *is = (ISPriv *)cod->decio->privateStack; if (is->type==IS_KeySensor) { // GF_Channel *ch = gf_list_get(cod->inChannels, 0); // gf_es_receive_sl_packet(ch->service, ch, buf, buf_size, &slh, GF_OK); IS_ProcessData((GF_SceneDecoder*)cod->decio, buf, buf_size, 0, 0, 0); } } gf_free(buf); #ifndef GPAC_DISABLE_X3D i=0; while ((n = (X_KeySensor*)gf_list_enum(term->x3d_sensors, &i))) { u16 tc[2]; u32 len; char szStr[10]; const unsigned short *ptr; if (gf_node_get_tag((GF_Node*)n) != TAG_X3D_KeySensor) continue; if (!n->enabled) return 0; if (keyPressed) { if (n->keyPress.buffer) gf_free(n->keyPress.buffer); tc[0] = keyPressed; tc[1] = 0; ptr = tc; len = gf_utf8_wcstombs(szStr, 10, &ptr); n->keyPress.buffer = (char*)gf_malloc(sizeof(char) * (len+1)); memcpy(n->keyPress.buffer, szStr, sizeof(char) * len); n->keyPress.buffer[len] = 0; gf_node_event_out_str((GF_Node *)n, "keyPress"); } if (keyReleased) { if (n->keyRelease.buffer) gf_free(n->keyRelease.buffer); tc[0] = keyReleased; tc[1] = 0; ptr = tc; len = gf_utf8_wcstombs(szStr, 10, &ptr); n->keyRelease.buffer = (char*)gf_malloc(sizeof(char) * (len+1)); memcpy(n->keyRelease.buffer, szStr, sizeof(char) * len); n->keyRelease.buffer[len] = 0; gf_node_event_out_str((GF_Node *)n, "keyRelease"); } if (actionKeyPressed) { n->actionKeyPress = actionKeyPressed; gf_node_event_out_str((GF_Node *)n, "actionKeyPress"); } if (actionKeyReleased) { n->actionKeyRelease = actionKeyReleased; gf_node_event_out_str((GF_Node *)n, "actionKeyRelease"); } if (shiftKeyDown) { n->shiftKey = (shiftKeyDown-1) ? 1 : 0; gf_node_event_out_str((GF_Node *)n, "shiftKey"); } if (controlKeyDown) { n->controlKey = (controlKeyDown-1) ? 1 : 0; gf_node_event_out_str((GF_Node *)n, "controlKey"); } if (altKeyDown) { n->altKey= (altKeyDown-1) ? 1 : 0; gf_node_event_out_str((GF_Node *)n, "altKey"); } if (keyPressed || actionKeyPressed || (shiftKeyDown-1) || (controlKeyDown-1) || (altKeyDown-1)) { if (!n->isActive) { n->isActive = 1; gf_node_event_out_str((GF_Node *)n, "isActive"); } } else if (n->isActive) { n->isActive = 0; gf_node_event_out_str((GF_Node *)n, "isActive"); } } #endif /*with KeySensor, we don't know if the key will be consumed or not, assume it is*/ return 1; }
void gf_term_mouse_input(GF_Terminal *term, GF_EventMouse *event) { s32 X, Y; u32 left_but_down, middle_but_down, right_but_down; SFFloat wheel_pos; u32 i; GF_Codec *cod; GF_BitStream *bs; GF_SLHeader slh; char *buf; u32 buf_size; Fixed bX, bY; if (!term || !gf_list_count(term->input_streams)) return; X = event->x; Y = event->y; left_but_down = middle_but_down = right_but_down = 0; wheel_pos = 0; switch (event->type) { case GF_EVENT_MOUSEDOWN: if (event->button==GF_MOUSE_RIGHT) right_but_down = 2; else if (event->button==GF_MOUSE_MIDDLE) middle_but_down = 2; else if (event->button==GF_MOUSE_LEFT) left_but_down = 2; break; case GF_EVENT_MOUSEUP: if (event->button==GF_MOUSE_RIGHT) right_but_down = 1; else if (event->button==GF_MOUSE_MIDDLE) middle_but_down = 1; else if (event->button==GF_MOUSE_LEFT) left_but_down = 1; break; case GF_EVENT_MOUSEWHEEL: wheel_pos = event->wheel_pos; break; case GF_EVENT_MOUSEMOVE: break; default: return; } /*get BIFS coordinates*/ gf_sc_map_point(term->compositor, X, Y, &bX, &bY); bX = gf_divfix(bX, term->compositor->scale_x); bY = gf_divfix(bY, term->compositor->scale_y); bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); /*If wheel is specified disable X and Y (bug from MS wheel handling)*/ if (wheel_pos) { gf_bs_write_int(bs, 0, 1); } else { gf_bs_write_int(bs, 1, 1); gf_bs_write_float(bs, FIX2FLT(bX)); gf_bs_write_float(bs, FIX2FLT(bY)); } gf_bs_write_int(bs, left_but_down ? 1 : 0, 1); if (left_but_down) gf_bs_write_int(bs, left_but_down-1, 1); gf_bs_write_int(bs, middle_but_down ? 1 : 0, 1); if (middle_but_down) gf_bs_write_int(bs, middle_but_down-1, 1); gf_bs_write_int(bs, right_but_down ? 1 : 0, 1); if (right_but_down) gf_bs_write_int(bs, right_but_down-1, 1); if (wheel_pos==0) { gf_bs_write_int(bs, 0, 1); } else { gf_bs_write_int(bs, 1, 1); gf_bs_write_float(bs, FIX2FLT(wheel_pos) ); } gf_bs_align(bs); gf_bs_get_content(bs, &buf, &buf_size); gf_bs_del(bs); memset(&slh, 0, sizeof(GF_SLHeader)); slh.accessUnitStartFlag = slh.accessUnitEndFlag = 1; slh.compositionTimeStampFlag = 1; /*note we could use an exact TS but it's not needed: since the input is generated locally we want it to be decoded as soon as possible, thus using 0 emulates permanent seeking on InputSensor stream, hence forces input frame resync*/ slh.compositionTimeStamp = 0; /*get all IS Mouse decoders and send frame*/ i=0; while ((cod = (GF_Codec*)gf_list_enum(term->input_streams, &i))) { ISPriv *is = (ISPriv *)cod->decio->privateStack; if (is->type==IS_Mouse) { GF_Channel *ch = (GF_Channel *)gf_list_get(cod->inChannels, 0); gf_es_receive_sl_packet(ch->service, ch, buf, buf_size, &slh, GF_OK); } } gf_free(buf); }