package com.jcumulus.server.rtmfp.application; /** * 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.Peer; import com.jcumulus.server.rtmfp.packet.*; import com.jcumulus.server.rtmfp.publisher.E; import com.jcumulus.server.rtmfp.publisher.FlowWriter; import com.google.common.base.Strings; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.concurrent.locks.LockSupport; import org.apache.log4j.Logger; // Referenced classes of package com.jcumulus.server.rtmfp.application: // G, I public class Publication { private static final Logger F = Logger.getLogger(Publication.class); private Peer E; private FlowWriter A; private boolean G; private String J; private int I; private Map H; private G D; private G C; private _A B; private class _A extends Thread { public void A() { D = true; interrupt(); } public void run() { long l = System.nanoTime(); do { if(D) break; l += G * 0xf4240L; A.D(); long l1 = l - System.nanoTime() - E * 0xf4240L; if(l1 > 0L) LockSupport.parkNanos(l1); } while(true); } protected static final long C = 0L; protected static final long B = 0xf4240L; protected long E; protected Object F; protected long G; protected volatile boolean D; final Publication A; private _A() { super(); A = Publication.this; F = new Object(); G = 20L; D = false; setPriority(10); E = 0L; // timing_shift } } public Publication(String s) { G = false; H = new HashMap(); D = new G(); C = new G(); B = new _A(); B.start(); F.info((new StringBuilder()).append("New publication ").append(s).toString()); J = s; } public boolean A(Peer p, int i, FlowWriter h, boolean flag) { Listener j = (Listener)H.get(Integer.valueOf(i)); if(j != null) { F.warn((new StringBuilder()).append("Listener ").append(i).append(" is already subscribed for publication ").append(I).toString()); return true; } Listener k = new Listener(i, this, h, flag); if(p.B(k)) { H.put(Integer.valueOf(i), k); h.A("Play.Reset", (new StringBuilder()).append("Playing and resetting ").append(J).toString()); h.A("Play.Start", (new StringBuilder()).append("Started playing ").append(J).toString()); k.C(); return true; } else { h.A("Play.Failed", (new StringBuilder()).append("Not authorized to play ").append(J).toString()); return false; } } public void A(Peer p, int i) { Listener j = (Listener)H.get(Integer.valueOf(i)); if(j == null) { F.warn((new StringBuilder()).append("Listener ").append(i).append(" is already unsubscribed of publication ").append(I).toString()); return; } else { p.A(j); H.remove(Integer.valueOf(i)); return; } } public void A(String s, String s1) { if(I == 0) { F.error((new StringBuilder()).append("Publication ").append(J).append(" is not published").toString()); return; } if(A != null) { if(!Strings.isNullOrEmpty(s)) A.A(s, s1); A.A("close"); } else { F.warn((new StringBuilder()).append("Publisher ").append(I).append(" has no controller to close it").toString()); } } public void A(Peer p, int i, FlowWriter h) throws Exception { if(I != 0) { if(h != null) h.A("Publish.BadName", (new StringBuilder()).append(J).append(" is already published").toString()); throw new Exception((new StringBuilder()).append(J).append(" is already published").toString()); } I = i; if(!p.A(this)) { String s = (new StringBuilder()).append("Not allowed to publish ").append(J).toString(); I = 0; if(h != null) h.A("Publish.BadName", s); throw new Exception(s); } E = p; A = h; G = false; Listener j; for(Iterator iterator = H.values().iterator(); iterator.hasNext(); j.A(J)) j = (Listener)iterator.next(); D(); if(h != null) h.A("Publish.Start", (new StringBuilder()).append(J).append(" is now published").toString()); } public void B(Peer p, int i) { B.A(); if(I != i) { F.warn((new StringBuilder()).append("Unpublish '").append(J).append("' operation with a ").append(i).append(" id different than its publisher ").append(I).append(" id").toString()); return; } Listener j; for(Iterator iterator = H.values().iterator(); iterator.hasNext(); j.B(J)) j = (Listener)iterator.next(); D(); p.B(this); D.E(); C.E(); I = 0; E = null; A = null; } public void D() { Listener i; for(Iterator iterator = H.values().iterator(); iterator.hasNext(); i.B()) i = (Listener)iterator.next(); } public void A(String s, Packet a) { if(I == 0) { F.error((new StringBuilder()).append("Data packet pushed on a publication ").append(I).append(" who is idle").toString()); return; } int i = a.H(); for(Iterator iterator = H.values().iterator(); iterator.hasNext(); a.E(i)) { Listener j = (Listener)iterator.next(); j.A(s, a); } E.A(this, s, a); } public void B(int i, AudioPacket a, int j) { int k = a.H(); if(j > 0) F.info((new StringBuilder()).append(j).append(" audio fragments lost on publication ").append(I).toString()); C.A(i, a.M(), j); for(Iterator iterator = H.values().iterator(); iterator.hasNext(); a.E(k)) { Listener l = (Listener)iterator.next(); l.B(i, a); } if(E != null) E.B(this, i, a); } public void A(int i, AudioPacket a, int j) { if(j > 0) G = false; if((a.K() & 0xf0) == 16) G = true; D.A(i, a.M(), j); if(j > 0) F.info((new StringBuilder()).append(j).append(" video fragments lost on publication ").append(I).toString()); if(!G) { F.debug((new StringBuilder()).append("No key frame available on publication ").append(I).append(", frame dropped to wait first key frame").toString()); D.G(); return; } int k = a.H(); for(Iterator iterator = H.values().iterator(); iterator.hasNext(); a.E(k)) { Listener l = (Listener)iterator.next(); l.A(i, a); } if(E != null) E.A(this, i, a); } public int B() { return I; } public Map A() { return H; } public String C() { return J; } }