Exemple #1
0
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();
}