int MediaThread::publishPacket(PacketData &packetData, const Name& packetPrefix, PacketNumber packetNo, PrefixMetaInfo prefixMeta, double captureTimestamp) { if (!faceProcessor_->getTransport()->getIsConnected()) return notifyError(-1, "transport is not connected"); Name prefix = packetPrefix; Segmentizer::SegmentList segments; if (RESULT_FAIL(Segmentizer::segmentize(packetData, segments, segSizeNoHeader_))) return notifyError(-1, "packet segmentation failed"); #ifdef DROP_FRAMES static int count = 0; count++; bool drop = (count%100 == 0); #endif #ifdef DELAY_FRAMES static int count2 = 0; count2++; bool delay = (count2 > 200 && count2 % 200 < 10); if (delay) { LogWarnC << "drop frame " << packetPrefix << std::endl; return segments.size(); } #endif try { // update metadata for the packet PacketData::PacketMetadata metadata = { NdnRtcUtils::currentFrequencyMeterValue(packetRateMeter_), NdnRtcUtils::millisecondTimestamp(), captureTimestamp}; packetData.setMetadata(metadata); prefixMeta.crcValue_ = packetData.getCrcValue(); Name metaSuffix = PrefixMetaInfo::toName(prefixMeta); for (Segmentizer::SegmentList::iterator it = segments.begin(); it != segments.end(); ++it) { // add segment # Name segmentName = prefix; segmentName.appendSegment(it-segments.begin()); // lookup for pending interests and construct metaifno accordingly SegmentData::SegmentMetaInfo meta = {0,0,0}; bool pitHit = (lookupPrefixInPit(segmentName, meta) != 0); // add name suffix meta info segmentName.append(metaSuffix); // pack into network data SegmentData segmentData(it->getDataPtr(), it->getPayloadSize(), meta); Data ndnData(segmentName); ndnData.getMetaInfo().setFreshnessPeriod(settings_->dataFreshnessMs_); ndnData.setContent(segmentData.getData(), segmentData.getLength()); settings_->keyChain_->sign(ndnData, settings_->certificateName_); if (memCache_.get() && !pitHit) { // according to http://named-data.net/doc/ndn-ccl-api/memory-content-cache.html#memorycontentcache-registerprefix-method // adding content should be synchronized with the processEvents // call; this must be done in calling routines memCache_->add(ndnData); LogTraceC << "added to cache " << segmentName << " " << ndnData.getContent().size() << " bytes" << std::endl; } else { SignedBlob encodedData = ndnData.wireEncode(); faceProcessor_->getTransport()->send(*encodedData); LogTraceC << "sent " << segmentName << " " << ndnData.getContent().size() << " bytes" << std::endl; } #if 0 // enable this if you want measuring outgoing bitrate w/o ndn overhead NdnRtcUtils::dataRateMeterMoreData(dataRateMeter_, ndnData.getContent().size()); #else // enable this if you want measuring outgoing bitrate with ndn overhead NdnRtcUtils::dataRateMeterMoreData(dataRateMeter_, ndnData.getDefaultWireEncoding().size()); #endif #ifdef DROP_FRAMES if (drop) { LogWarnC << "drop frame " << packetPrefix << std::endl; break; } #endif } // for cleanPitForFrame(prefix); } catch (std::exception &e) { return notifyError(RESULT_ERR, "got error from ndn library while sending data: %s", e.what()); } int64_t timestamp = NdnRtcUtils::millisecondTimestamp(); if (publishingTimestampMs_) { int64_t delay = timestamp-publishingTimestampMs_; ((delay > FRAME_DELAY_DEADLINE) ? LogWarnC : LogTraceC) << "frame publishing delay " << delay << " (" << packetPrefix << ")" << std::endl; } publishingTimestampMs_ = timestamp; return segments.size(); }