package com.jcumulus.server.rtmfp.publisher;
/**
* jCumulus is a Java port of Cumulus OpenRTMP
*
* Copyright 2011 OpenRTMFP
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License received along this program for more
* details (or else see http://www.gnu.org/licenses/).
*
*
* This file is a part of jCumulus.
*/
import com.jcumulus.server.rtmfp.packet.*;
import com.jcumulus.server.rtmfp.ISession;
import com.jcumulus.server.rtmfp.Peer;
import com.jcumulus.server.rtmfp.pipe.C;
import com.jcumulus.server.rtmfp.flow.H;
import com.jcumulus.server.rtmfp.stream.BinaryWriter;
import com.jcumulus.server.rtmfp.stream.B;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.log4j.Logger;
public class E
{
private static final Logger F = Logger.getLogger(E.class);
public static final Integer N = Integer.valueOf(128);
public static final Integer C = Integer.valueOf(16);
public static final Integer M = Integer.valueOf(32);
public static final Integer H = Integer.valueOf(2);
public static final Integer E = Integer.valueOf(1);
public static com.jcumulus.server.rtmfp.application.C I = new com.jcumulus.server.rtmfp.application.C();
protected int A;
private int J;
protected Peer K;
private boolean G;
private ISession D;
private com.jcumulus.server.rtmfp.publisher.D B;
protected com.jcumulus.server.rtmfp.publisher.FlowWriter O;
private Map P;
private String L;
public E(int i, byte abyte0[], String s, Peer p, ISession d)
{
P = new HashMap();
A = i;
J = 0;
K = p;
G = false;
B = null;
D = d;
O = new com.jcumulus.server.rtmfp.publisher.FlowWriter(abyte0, d);
O.C(i);
O.C(s);
}
public void C()
{
E();
O.C();
}
void E()
{
if(G)
return;
if(O.G() != null)
F.debug((new StringBuilder()).append("Flow ").append(A).append(" consumed").toString());
G = true;
}
protected void A(String s)
{
F.error((new StringBuilder()).append("Flow ").append(A).append(" failed : %s").append(s).toString());
if(!G)
{
B b = D.A((byte)94, com.jcumulus.server.rtmfp.pipe.C.A(A) + 1, null);
b.D(A);
b.B((byte)0);
}
}
private byte B(AudioPacket a)
{
if(a.I() == 0)
return 0;
byte byte0 = a.L();
switch(byte0)
{
case 17: // '\021'
a.D(1);
// fall through
case 20: // '\024'
a.D(4);
return 20;
case 15: // '\017'
a.D(5);
break;
case 4: // '\004'
a.D(4);
break;
case 2: // '\002'
case 3: // '\003'
case 5: // '\005'
case 6: // '\006'
case 7: // '\007'
case 10: // '\n'
case 11: // '\013'
case 12: // '\f'
case 13: // '\r'
case 14: // '\016'
case 16: // '\020'
case 18: // '\022'
case 19: // '\023'
default:
F.error((new StringBuilder()).append("Unpacking type '").append(byte0).append("' unknown").toString());
break;
case 1: // '\001'
case 8: // '\b'
case 9: // '\t'
break;
}
return byte0;
}
public void F()
{
int i = 0;
ArrayList arraylist = new ArrayList();
int j = J;
boolean flag = false;
Integer integer;
for(Iterator iterator = P.keySet().iterator(); iterator.hasNext();)
integer = (Integer)iterator.next();
int k = B == null ? 127 : B.B() <= 16128 ? 16128 - B.B() : 0;
if(O.G() == null)
k = 0;
B b = D.A((byte)81, com.jcumulus.server.rtmfp.pipe.C.A(A) + com.jcumulus.server.rtmfp.pipe.C.A(k) + com.jcumulus.server.rtmfp.pipe.C.A(J) + i, null);
b.D(A);
b.D(k);
b.D(J);
Integer integer1;
for(Iterator iterator1 = arraylist.iterator(); iterator1.hasNext(); b.D(integer1.intValue()))
integer1 = (Integer)iterator1.next();
A();
O.A();
}
public void A(int i, int j, AudioPacket a, byte byte0)
{
if(G)
return;
int k = J + 1;
if(i < k)
{
F.debug((new StringBuilder()).append("Stage ").append(i).append(" on flow ").append(A).append(" has already been received").toString());
return;
}
if(j > i)
{
F.warn((new StringBuilder()).append("DeltaNAck ").append(j).append(" superior to stage ").append(i).append(" on flow ").append(A).toString());
j = i;
}
if(J < i - j)
{
Iterator iterator = P.keySet().iterator();
do
{
if(!iterator.hasNext())
break;
Integer integer = (Integer)iterator.next();
if(integer.intValue() > i)
break;
AudioPacket a1 = ((com.jcumulus.server.rtmfp.publisher.B)P.get(integer)).B();
A(integer.intValue(), a1, ((com.jcumulus.server.rtmfp.publisher.B)P.get(integer)).A());
if(G)
return;
iterator.remove();
} while(true);
k = i;
}
if(i > k)
{
com.jcumulus.server.rtmfp.publisher.B b = (com.jcumulus.server.rtmfp.publisher.B)P.get(Integer.valueOf(i));
if(b == null)
{
P.put(Integer.valueOf(i), new com.jcumulus.server.rtmfp.publisher.B(a, byte0));
if(P.size() > 100)
F.debug((new StringBuilder()).append("fragmentMap.size()=").append(P.size()).toString());
} else
{
F.debug((new StringBuilder()).append("Stage ").append(i).append(" on flow ").append(A).append(" has already been received").toString());
}
} else
{
A(k++, a, byte0);
Iterator iterator1 = P.keySet().iterator();
do
{
if(!iterator1.hasNext())
break;
Integer integer1 = (Integer)iterator1.next();
if(integer1.intValue() > k)
break;
AudioPacket a2 = ((com.jcumulus.server.rtmfp.publisher.B)P.get(integer1)).B();
A(k++, a2, ((com.jcumulus.server.rtmfp.publisher.B)P.get(integer1)).A());
if(G)
break;
iterator1.remove();
} while(true);
}
}
void A(int i, AudioPacket a, byte byte0)
{
if(i <= J)
{
F.error((new StringBuilder()).append("Stage ").append(i).append(" not sorted on flow").append(A).toString());
return;
}
if(i > J + 1)
{
int j = i - J - 1;
J = i;
if(B != null)
B = null;
if((byte0 != 0) & (M != null))
{
A(j + 1);
return;
}
A(j);
} else
{
J = i;
}
if((byte0 & H.intValue()) != 0)
{
if(B != null)
B = null;
return;
}
if((byte0 & M.intValue()) != 0)
{
if(B == null)
{
F.warn("A received message tells to have a 'beforepart' and nevertheless partbuffer is empty, certainly some packets were lost");
A(1);
B = null;
return;
}
B.A(a);
if((byte0 & C.intValue()) != 0)
return;
a = B.A();
} else
if((byte0 & C.intValue()) != 0)
{
if(B != null)
{
F.error("A received message tells to have not 'beforepart' and nevertheless partbuffer exists");
A(B.B());
}
B = new com.jcumulus.server.rtmfp.publisher.D(a);
return;
}
byte byte1 = B(a);
if(byte1 != 0)
{
O.A(Double.valueOf(0.0D));
String s = null;
com.jcumulus.server.rtmfp.flow.B b = new com.jcumulus.server.rtmfp.flow.B(a);
if(byte1 == 20 || byte1 == 15)
{
s = b.E();
if(byte1 == 20)
{
O.A(b.N());
if(b.G() == com.jcumulus.server.rtmfp.flow.H.Null)
b.P();
}
}
try
{
switch(byte1)
{
case 15: // '\017'
case 20: // '\024'
A(s, b);
break;
case 8: // '\b'
C(a);
break;
case 9: // '\t'
A(a);
break;
default:
A(byte1, a);
break;
}
}
catch(Exception exception)
{
F.error(exception.getMessage(), exception);
L = (new StringBuilder()).append("flow error, ").append(exception).toString();
}
}
O.A(Double.valueOf(0.0D));
if(B != null)
B = null;
if((byte0 & E.intValue()) != 0)
E();
}
protected void A(String s, com.jcumulus.server.rtmfp.flow.B b)
{
F.error((new StringBuilder()).append("Message '").append(s).append("' unknown for flow ").append(A).toString());
}
protected void A(byte byte0, Packet a)
{
F.error((new StringBuilder()).append("Raw message unknown for flow ").append(A).toString());
}
protected void C(AudioPacket a)
{
F.error((new StringBuilder()).append("Audio packet untreated for flow ").append(A).toString());
}
protected void A(AudioPacket a)
{
F.error((new StringBuilder()).append("Video packet untreated for flow ").append(A).toString());
}
protected void A(int i)
{
F.info((new StringBuilder()).append(i).append(" fragments lost on flow").append(A).toString());
}
protected void A()
{
}
public boolean B()
{
return G;
}
public int D()
{
return A;
}
public String G()
{
return L;
}
}