
org.jitsi.impl.neomedia.transform.RetransmissionRequesterImpl Maven / Gradle / Ivy
/*
* Copyright @ 2017 Atlassian Pty Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jitsi.impl.neomedia.transform;
import org.jitsi.impl.neomedia.rtp.*;
import org.jitsi.service.neomedia.*;
import org.jitsi.service.neomedia.codec.*;
import org.jitsi.service.neomedia.format.*;
import org.jitsi.utils.*;
import org.jitsi.utils.concurrent.*;
import org.jitsi.utils.logging.*;
/**
* Creates classes to handle both the detection of loss and the creation
* and sending of nack packets, and a scheduler to allow for nacks to be
* re-transmitted at a set interval
*
* @author bbaldino
*/
public class RetransmissionRequesterImpl
extends SinglePacketTransformerAdapter
implements TransformEngine, RetransmissionRequester
{
/**
* The Logger used by the RetransmissionRequesterDelegate class
* and its instances to print debug information.
*/
private static final Logger logger
= Logger.getLogger(RetransmissionRequesterImpl.class);
/**
* Whether this {@link RetransmissionRequester} is enabled or not.
*/
private boolean enabled = true;
/**
* Whether this PacketTransformer has been closed.
*/
private boolean closed = false;
/**
* The delegate for this {@link RetransmissionRequesterImpl} which handles
* the main logic for determining when to send nacks
*/
private final RetransmissionRequesterDelegate retransmissionRequesterDelegate;
/**
* The {@link MediaStream} that this instance belongs to.
*/
private final MediaStream stream;
/**
* Create a single executor to service the nack processing for all the
* {@link RetransmissionRequesterImpl} instances
*/
private static RecurringRunnableExecutor recurringRunnableExecutor
= new RecurringRunnableExecutor(
RetransmissionRequesterImpl.class.getSimpleName());
public RetransmissionRequesterImpl(MediaStream stream)
{
this.stream = stream;
retransmissionRequesterDelegate = new RetransmissionRequesterDelegate(stream, new TimeProvider());
recurringRunnableExecutor.registerRecurringRunnable(retransmissionRequesterDelegate);
retransmissionRequesterDelegate.setWorkReadyCallback(new Runnable(){
@Override
public void run()
{
recurringRunnableExecutor.startOrNotifyThread();
}
});
}
/**
* {@inheritDoc}
*
* Implements {@link SinglePacketTransformer#reverseTransform(RawPacket)}.
*/
@Override
public RawPacket reverseTransform(RawPacket pkt)
{
if (enabled && !closed)
{
Long ssrc;
int seq;
MediaFormat format = stream.getFormat(pkt.getPayloadType());
if (format == null)
{
ssrc = null;
seq = -1;
logger.warn("format_not_found" +
",stream_hash=" + stream.hashCode());
}
else if (Constants.RTX.equalsIgnoreCase(format.getEncoding()))
{
MediaStreamTrackReceiver receiver
= stream.getMediaStreamTrackReceiver();
RTPEncodingDesc encoding = receiver.findRTPEncodingDesc(pkt);
if (encoding != null)
{
ssrc = encoding.getPrimarySSRC();
seq = pkt.getOriginalSequenceNumber();
}
else
{
ssrc = null;
seq = -1;
logger.warn("encoding_not_found" +
",stream_hash=" + stream.hashCode());
}
}
else
{
ssrc = pkt.getSSRCAsLong();
seq = pkt.getSequenceNumber();
}
if (ssrc != null)
{
retransmissionRequesterDelegate.packetReceived(ssrc, seq);
}
}
return pkt;
}
/**
* {@inheritDoc}
*/
@Override
public void close()
{
closed = true;
recurringRunnableExecutor.deRegisterRecurringRunnable(retransmissionRequesterDelegate);
}
// TransformEngine methods
/**
* {@inheritDoc}
*/
@Override
public PacketTransformer getRTPTransformer()
{
return this;
}
/**
* {@inheritDoc}
*/
@Override
public PacketTransformer getRTCPTransformer()
{
return null;
}
// RetransmissionRequester methods
/**
* {@inheritDoc}
*/
@Override
public void enable(boolean enable)
{
this.enabled = enable;
}
/**
* {@inheritDoc}
*/
@Override
public void setSenderSsrc(long ssrc)
{
this.retransmissionRequesterDelegate.setSenderSsrc(ssrc);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy