/*
* myLib - https://github.com/taktod/myLib
* Copyright (c) 2014 ttProject. All rights reserved.
*
* Licensed under The MIT license.
*/
package com.ttProject.media.mpegts;
import java.nio.ByteBuffer;
import java.util.List;
import com.ttProject.media.extra.Bit;
import com.ttProject.media.extra.Bit1;
import com.ttProject.media.extra.Bit2;
import com.ttProject.media.extra.Bit4;
import com.ttProject.media.extra.Bit5;
import com.ttProject.media.extra.Bit8;
import com.ttProject.media.extra.BitConnector;
import com.ttProject.media.extra.BitLoader;
import com.ttProject.nio.channels.IReadChannel;
/**
* プログラム系のpacketの親クラス
* @author taktod
*/
public abstract class ProgramPacket extends Packet {
private Bit8 pointerField; // 0000 0000
private Bit8 tableId; // packet固定値
private Bit1 sectionSyntaxIndicator; // 1
private Bit1 reservedFutureUse1; // 0
private Bit2 reserved1; // 11
private short sectionLength; // 12bit
private short programNumber; // 16bit
private Bit2 reserved2; // 11
private Bit5 versionNumber; // 00000
private Bit1 currentNextOrder; // 1
private Bit8 sectionNumber; // 00000000
private Bit8 lastSectionNumber; // 00000000
/**
* コンストラクタ
* @param position
* @param buffer
*/
public ProgramPacket(int position) {
super(position);
}
/**
* ヘッダー部分の解析補助補助
*/
protected void analyzeHeader(IReadChannel channel) throws Exception {
super.analyzeHeader(channel);
pointerField = new Bit8();
tableId = new Bit8();
sectionSyntaxIndicator = new Bit1();
reservedFutureUse1 = new Bit1();
reserved1 = new Bit2();
Bit4 sectionLength_1 = new Bit4();
Bit8 sectionLength_2 = new Bit8();
Bit8 programNumber_1 = new Bit8();
Bit8 programNumber_2 = new Bit8();
reserved2 = new Bit2();
versionNumber = new Bit5();
currentNextOrder = new Bit1();
sectionNumber = new Bit8();
lastSectionNumber = new Bit8();
BitLoader bitLoader = new BitLoader(channel);
bitLoader.load(pointerField, tableId, sectionSyntaxIndicator, reservedFutureUse1, reserved1,
sectionLength_1, sectionLength_2, programNumber_1, programNumber_2,
reserved2, versionNumber, currentNextOrder, sectionNumber, lastSectionNumber);
sectionLength = (short)((sectionLength_1.get() << 8) | sectionLength_2.get());
programNumber = (short)((programNumber_1.get() << 8) | programNumber_2.get());
}
public short getSectionLength() {
return sectionLength;
}
// TODO setSectionLengthを呼び出して内容がかわったときに、データをただしくする動作がぬけているので、やっておく。
public void setSectionLength(short length) {
sectionLength = length;
}
/**
* ファイルに書き出す場合のBufferデータを応答する
*/
@Override
public ByteBuffer getBuffer() throws Exception {
// TODO counterの書き込みの部分は、データを作成したときに管理するのではなくて、データの書き出しを実施するときに管理した方がよさそう・・・
ByteBuffer result = ByteBuffer.allocate(188);
// 情報をbit配列に戻して応答する。
BitConnector bitConnector = new BitConnector();
ByteBuffer buffer = bitConnector.connect(getBits());
Crc32 crc32 = new Crc32();
while(buffer.remaining() > 0) {
byte data = buffer.get();
if(buffer.position() > 5) { // crc32は6バイト目から計算にいれる。
crc32.update(data);
}
result.put(data);
}
int crc32Val = (int)crc32.getValue();
result.put((byte)((crc32Val >>> 24) & 0xFF));
result.put((byte)((crc32Val >>> 16) & 0xFF));
result.put((byte)((crc32Val >>> 8) & 0xFF));
result.put((byte)(crc32Val & 0xFF));
while(result.position() != result.limit()) {
result.put((byte)0xFF);
}
result.flip();
return result;
}
@Override
public List<Bit> getBits() {
List<Bit> list = super.getBits();
list.add(pointerField);
list.add(tableId);
list.add(sectionSyntaxIndicator);
list.add(reservedFutureUse1);
list.add(reserved1);
list.add(new Bit4(sectionLength >>> 8));
list.add(new Bit8(sectionLength));
list.add(new Bit8(programNumber >>> 8));
list.add(new Bit8(programNumber));
list.add(reserved2);
list.add(versionNumber);
list.add(currentNextOrder);
list.add(sectionNumber);
list.add(lastSectionNumber);
return list;
}
@Override
public String toString() {
StringBuilder data = new StringBuilder();
data.append(" ");
data.append("parentPacket:");
data.append(" ti:").append(Integer.toHexString(tableId.get()));
data.append(" sso:").append(sectionSyntaxIndicator);
data.append(" rfu1:").append(reservedFutureUse1);
data.append(" r1:").append(reserved1);
data.append(" sl:").append(Integer.toHexString(sectionLength));
data.append(" pn:").append(Integer.toHexString(programNumber));
data.append(" r2:").append(reserved2);
data.append(" vn:").append(versionNumber);
data.append(" cno:").append(currentNextOrder);
data.append(" sn:").append(sectionNumber);
data.append(" lsn:").append(lastSectionNumber);
data.append("\n").append(super.toString());
return data.toString();
}
}