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.ISession;
import com.jcumulus.server.rtmfp.packet.*;
import com.jcumulus.server.rtmfp.pipe.C;
import com.jcumulus.server.rtmfp.application.VideoWriter;
import com.google.common.base.Strings;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;
import org.apache.log4j.Logger;
public class FlowWriter
{
private static final Logger G = Logger.getLogger(FlowWriter.class);
private static J S = new J();
private int J;
private boolean K;
private int C;
private byte I[];
private ISession H;
private boolean B;
private L A;
private final List P = new ArrayList();
private int N;
private final List O = new ArrayList();
private int L;
private int M;
private int D;
private int F;
private Double E;
private String R;
private int Q;
public FlowWriter(byte abyte0[], ISession d)
{
A = new L();
K = false;
J = 0;
N = 0;
L = 0;
B = false;
E = Double.valueOf(0.0D);
Q = 0;
C = 0;
H = d;
I = abyte0;
F = 0;
M = 0;
D = 0;
d.B(this);
}
public com.jcumulus.server.rtmfp.application.AudioWriter B()
{
return new com.jcumulus.server.rtmfp.application.AudioWriter(I, H);
}
public VideoWriter K()
{
return new VideoWriter(I, H);
}
public void F()
{
B = true;
I();
}
public void D(String s)
{
G.warn((new StringBuilder()).append("FlowWriter ").append(J).append(" has failed : ").append(s).toString());
N = L = M = D = 0;
I();
if(B)
{
return;
} else
{
H.B(this);
return;
}
}
public void I()
{
}
public void C()
{
if(B)
return;
if(N > 0)
if(D() != 0);
B = true;
A();
}
protected com.jcumulus.server.rtmfp.flow.A C(String s, String s1)
{
return A("_result", s, s1);
}
public com.jcumulus.server.rtmfp.flow.A A(String s, String s1)
{
return A("onStatus", s, s1);
}
public com.jcumulus.server.rtmfp.flow.A B(String s, String s1)
{
return A("_error", s, s1);
}
public void A(AudioPacket a)
{
int i = a.J();
if(i == 0)
{
G.error("Negative acknowledgment");
D("Negative acknowledgment");
return;
}
int j = L;
int k = a.J();
int l = L + 1;
if(k > N)
{
G.error((new StringBuilder()).append("Acknowledgment received ").append(k).append(" superior than the current sending stage ").append(N).append(" on flowWriter ").append(J).toString());
L = N;
} else
if(k <= L)
{
if(a.I() == 0)
G.debug((new StringBuilder()).append("Acknowledgment ").append(k).append(" obsolete on flowWriter ").append(J).toString());
} else
{
L = k;
}
int i1 = L;
int j1 = a.H();
while(a.I() > 0)
i1 += a.J() + a.J() + 2;
if(j1 != a.H())
a.E(j1);
int k1 = 0;
int l1 = 0;
boolean flag = false;
boolean flag1 = true;
boolean flag2 = false;
synchronized(O)
{
ListIterator listiterator = O.listIterator();
do
{
if(flag2 || !listiterator.hasNext())
break;
I i2 = (I)listiterator.next();
if(i2.B().size() == 0)
{
G.error((new StringBuilder()).append("Message ").append(l + 1).append(" is bad formatted on flowWriter ").append(J).toString());
} else
{
Integer ainteger[] = (Integer[])i2.B().keySet().toArray(new Integer[0]);
Integer integer = ainteger[0];
int j2 = 0;
do
{
if(j2 >= ainteger.length)
break;
if(L >= l)
{
i2.B().remove(ainteger[0]);
ainteger = (Integer[])i2.B().keySet().toArray(new Integer[0]);
j2 = 0;
if(j2 < ainteger.length)
integer = ainteger[j2];
D++;
l++;
continue;
}
do
{
if(flag2 || k1 != 0)
break;
if(k1 == 0)
if(a.I() > 0)
{
k1 = a.J() + 1;
l1 = k + 1;
k = l1 + k1 + a.J();
} else
{
flag2 = true;
break;
}
if(l1 > N)
{
G.error((new StringBuilder()).append("Lost information received ").append(l1).append(" have not been yet sent on flowWriter ").append(J).toString());
flag2 = true;
break;
}
if(l1 > L)
break;
k1--;
l1++;
} while(true);
if(flag2)
break;
if(l1 != l)
{
if(flag)
{
l++;
if(j2 < ainteger.length - 1)
{
j2++;
integer = ainteger[j2];
}
flag1 = true;
} else
{
L = l;
}
} else
if(!i2.A())
{
if(flag)
{
j2++;
integer = ainteger[j2];
l++;
flag1 = true;
} else
{
G.debug((new StringBuilder()).append("FlowWriter ").append(J).append(" : message ").append(l).append(" lost").toString());
D--;
M++;
L = l;
}
k1--;
l1++;
} else
{
flag = true;
if(((Integer)i2.B().get(integer)).intValue() >= i1 || k == l1 + 2)
{
l++;
flag1 = true;
k1--;
l1++;
if(j2 < ainteger.length - 1)
{
j2++;
integer = ainteger[j2];
}
} else
{
G.debug((new StringBuilder()).append("FlowWriter ").append(J).append(" : stage ").append(l).append(" repeated").toString());
int k2 = integer.intValue();
Packet b1 = i2.A(k2);
int i3 = b1.I();
i2.B().put(integer, Integer.valueOf(N));
int j3 = i3;
byte byte0 = 0;
if(k2 > 0)
byte0 |= com.jcumulus.server.rtmfp.publisher.E.M.intValue();
if(j2 < ainteger.length - 1)
{
j2++;
integer = ainteger[j2];
byte0 |= com.jcumulus.server.rtmfp.publisher.E.C.intValue();
j3 = integer.intValue() - k2;
}
com.jcumulus.server.rtmfp.stream.B b2 = H.B();
int k3 = j3 + 4;
if(!flag1 && k3 > b2.D())
{
H.A(false);
flag1 = true;
}
if(flag1)
k3 += D(l);
if(k3 > b2.D())
H.A(false);
k3 -= 3;
A(H.A(((byte)(flag1 ? 16 : 17)), k3, null), l, byte0, flag1, b1, j3);
i3 -= j3;
flag1 = false;
k1--;
l1++;
l++;
}
}
} while(true);
if(i2.B().size() == 0)
{
if(i2.A())
F--;
if(D > 0)
{
Packet b = i2.D();
int l2 = b.I();
A(D, M, b, l2);
D = M = 0;
}
listiterator.remove();
}
}
} while(true);
}
if(k1 > 0 && a.I() > 0)
G.error((new StringBuilder()).append("Some lost information received have not been yet sent on flowWriter ").append(J).toString());
if(F == 0)
A.B();
else
if(L > j || flag)
A.A();
}
public void A(int i)
{
if(i >= D())
{
G.error((new StringBuilder()).append("Impossible to cancel ").append(i).append(" message on flowWriter ").append(J).toString());
return;
}
synchronized(P)
{
for(int j = i; j < P.size(); j++)
P.remove(i);
}
}
public void A(byte abyte0[], int i)
{
A(abyte0, i, ((byte []) (null)), 0);
}
public void A(byte abyte0[], int i, byte abyte1[], int j)
{
if(B || I == null || H.A())
return;
G g = new G(abyte0, i, abyte1, j);
synchronized(P)
{
P.add(g);
}
A();
}
private K H()
{
if(B || I == null || H.A())
return S;
K k = new K();
synchronized(P)
{
P.add(k);
}
return k;
}
public com.jcumulus.server.rtmfp.stream.BinaryWriter A(boolean flag)
{
K k = H();
if(!flag)
{
k.E().B((byte)4);
k.E().A(0);
}
return k.E();
}
public com.jcumulus.server.rtmfp.flow.F B(String s)
{
K k = H();
k.E().B((byte)15);
k.E().B((byte)0);
k.E().A(0);
k.F().A(s);
return k.F();
}
private void A(com.jcumulus.server.rtmfp.stream.BinaryWriter a, String s, double d)
{
a.B((byte)20);
a.A(0);
a.B((byte)2);
a.D(s.getBytes());
a.B((byte)0);
a.A(d);
a.B((byte)5);
}
public com.jcumulus.server.rtmfp.flow.F A(String s)
{
K k = H();
A(k.E(), s, 0.0D);
return k.F();
}
public com.jcumulus.server.rtmfp.flow.F J()
{
K k = H();
A(k.E(), "_result", E.doubleValue());
return k.F();
}
com.jcumulus.server.rtmfp.flow.A A(String s, String s1, String s2)
{
K k = H();
A(k.E(), s, E.doubleValue());
String s3 = R;
if(!Strings.isNullOrEmpty(s1))
{
s3 = (new StringBuilder()).append(s3).append(".").toString();
s3 = (new StringBuilder()).append(s3).append(s1).toString();
}
boolean flag = k.F().D();
k.F().B(true);
com.jcumulus.server.rtmfp.flow.A a = new com.jcumulus.server.rtmfp.flow.A(k.F());
if(s.equals("_error"))
a.A("level", "error");
else
a.A("level", "status");
a.A("code", s3);
if(!Strings.isNullOrEmpty(s2))
a.A("description", s2);
k.F().B(flag);
return a;
}
public void A()
{
B(false);
}
public void B(boolean flag)
{
boolean flag1 = !H.A(this);
synchronized(P)
{
for(Iterator iterator = P.iterator(); iterator.hasNext();)
{
I i = (I)iterator.next();
if(i.A())
{
F++;
A.C();
}
int j = 0;
Packet b = i.D();
int k = b.I();
do
{
com.jcumulus.server.rtmfp.stream.B b1 = H.B();
if(b1.D() < 12)
{
H.A(false);
flag1 = true;
}
boolean flag2 = flag1;
int l = k;
int i1 = l + 4;
N++;
if(flag2)
i1 += D(N);
byte byte0 = 0;
if(j > 0)
byte0 |= com.jcumulus.server.rtmfp.publisher.E.M.intValue();
if(i1 > b1.D())
{
byte0 |= com.jcumulus.server.rtmfp.publisher.E.C.intValue();
l = b1.D() - (i1 - l);
i1 = b1.D();
flag1 = true;
} else
{
flag1 = false;
}
i1 -= 3;
A(H.A(((byte)(flag2 ? 16 : 17)), (short)i1, this), N, byte0, flag2, b, l);
i.B().put(Integer.valueOf(j), Integer.valueOf(N));
k -= l;
j += l;
} while(k > 0);
synchronized(O)
{
O.add(i);
}
}
P.clear();
}
if(flag)
H.A(true);
}
int D(int i)
{
int j = com.jcumulus.server.rtmfp.pipe.C.A(J);
j += com.jcumulus.server.rtmfp.pipe.C.A(i);
if(L > i)
G.error((new StringBuilder()).append("stageAck ").append(L).append(" superior to stage ").append(i).append(" on flowWriter ").append(J).toString());
j += com.jcumulus.server.rtmfp.pipe.C.A(i - L);
j += L <= 0 ? I.length + (C != 0 ? 4 + com.jcumulus.server.rtmfp.pipe.C.A(C) : 2) : 0;
return j;
}
public void A(com.jcumulus.server.rtmfp.stream.B b, int i, byte byte0, boolean flag, Packet b1, int j)
{
if(L == 0 && flag)
byte0 |= com.jcumulus.server.rtmfp.publisher.E.N.intValue();
if(j == 0)
byte0 |= com.jcumulus.server.rtmfp.publisher.E.H.intValue();
if(B)
byte0 |= com.jcumulus.server.rtmfp.publisher.E.E.intValue();
G.debug((new StringBuilder()).append("FlowWriter ").append(J).append(" stage ").append(i).toString());
b.B(byte0);
if(flag)
{
b.D(J);
b.D(i);
b.D((byte0 & com.jcumulus.server.rtmfp.publisher.E.H.intValue()) == 0 ? i - L : 0);
if(L == 0)
{
b.C(I);
if(C > 0)
{
b.B((byte)(1 + com.jcumulus.server.rtmfp.pipe.C.A(C)));
b.B((byte)10);
b.D(C);
}
b.B((byte)0);
}
}
if(j > 0)
b.B(b1.F(j));
}
protected void A(int i, int j, Packet b, int k)
{
}
public int D()
{
synchronized (this.P)
{
return this.P.size();
}
}
public int E()
{
return J;
}
public void B(int i)
{
J = i;
}
public void C(int i)
{
C = i;
}
public void C(String s)
{
R = s;
}
public void A(Double double1)
{
E = double1;
}
public byte[] G()
{
return I;
}
}