/* * myLib - https://github.com/taktod/myLib * Copyright (c) 2014 ttProject. All rights reserved. * * Licensed under The MIT license. */ package com.ttProject.rtmp.header; import org.apache.log4j.Logger; import io.netty.buffer.ByteBuf; import com.ttProject.rtmp.decode.Message; import com.ttProject.rtmp.header.type.Type0; import com.ttProject.rtmp.header.type.Type1; import com.ttProject.rtmp.header.type.Type2; import com.ttProject.rtmp.header.type.Type3; import com.ttProject.rtmp.message.MessageType; /** * HeaderFactory * @author taktod * factory class for IRtmpHeader */ public class HeaderFactory { @SuppressWarnings("unused") private static Logger logger = Logger.getLogger(HeaderFactory.class); private static HeaderFactory instance = new HeaderFactory(); /** * constructor */ private HeaderFactory() { } /** * singleton getter. * @return */ public static synchronized HeaderFactory getInstance() { return instance; } /** * factory method for header. * @param in * @param messages * @return */ public IRtmpHeader getHeader(ByteBuf in, Message[] messages) { // readHeaderType and chunkStreamId int firstByte = in.readByte(); int csId = 0; int headerTypeValue = (firstByte >> 6) & 0x03; switch(firstByte & 0x3F) { case 0: csId = in.readByte() & 0xFF; break; case 1: csId = in.readShort() & 0xFFFF; break; default: csId = firstByte & 0x3F; break; } // setup data. RtmpHeader header = null; switch(HeaderType.getType(headerTypeValue)) { case Type0: { header = new Type0(); header.setCsId(csId); header.setTime(in.readMedium()); header.setSize(in.readMedium()); header.setMessageType(MessageType.getType(in.readByte())); // これはなぜかlittleEndianらしい。 int a,b,c,d; a = in.readByte(); b = in.readByte(); c = in.readByte(); d = in.readByte(); header.setStreamId((d << 24) | (c << 16) | (b << 8) | a); if(header.getTime() == IRtmpHeader.MAX_TIME) { header.setTime(in.readInt()); } } break; case Type1: { IRtmpHeader prevHeader = messages[csId].getHeader(); header = new Type1(); header.setCsId(csId); header.setDeltaTime(in.readMedium()); header.setSize(in.readMedium()); header.setMessageType(MessageType.getType(in.readByte())); header.setStreamId(prevHeader.getStreamId()); if(header.getDeltaTime() == IRtmpHeader.MAX_TIME) { header.setDeltaTime(in.readInt()); } } break; case Type2: { IRtmpHeader prevHeader = messages[csId].getHeader(); header = new Type2(); header.setCsId(csId); header.setDeltaTime(in.readMedium()); header.setSize(prevHeader.getSize()); header.setMessageType(prevHeader.getMessageType()); header.setStreamId(prevHeader.getStreamId()); if(header.getDeltaTime() == IRtmpHeader.MAX_TIME) { header.setDeltaTime(in.readInt()); } } break; case Type3: { IRtmpHeader prevHeader = messages[csId].getHeader(); header = new Type3(); header.setCsId(csId); header.setDeltaTime(prevHeader.getDeltaTime()); header.setSize(prevHeader.getSize()); header.setMessageType(prevHeader.getMessageType()); header.setStreamId(prevHeader.getStreamId()); } break; } return header; } @Deprecated public IRtmpHeader getHeader(MessageType type, int time, int size) { RtmpHeader header = (RtmpHeader)getHeader(type); header.setSize(size); header.setTime(time); return header; } public IRtmpHeader getHeader(MessageType type) { Type0 header = new Type0(); header.setCsId(MessageType.getDefaultCsId(type)); header.setMessageType(type); return header; } }