/* * myLib - https://github.com/taktod/myLib * Copyright (c) 2014 ttProject. All rights reserved. * * Licensed under The MIT license. */ package com.ttProject.media.mpegts.field; import java.util.ArrayList; import java.util.List; import com.ttProject.media.extra.Bit; import com.ttProject.media.extra.Bit3; import com.ttProject.media.extra.Bit4; import com.ttProject.media.extra.Bit5; import com.ttProject.media.extra.Bit8; import com.ttProject.media.extra.BitLoader; import com.ttProject.media.mpegts.CodecType; import com.ttProject.media.mpegts.descriptor.Descriptor; import com.ttProject.nio.channels.IReadChannel; /** * pmtのelementaryStreamのデータ記述部 * @author taktod */ public class PmtElementaryField { // あたらしくトラックをつくった場合の次のpid private static short nextTrackPid = 0x0100; private Bit8 streamType; private Bit3 reserved1; private short pid; // 13bit private Bit4 reserved2; private short esInfoLength; // 12bit // ESDescriptor /* * vlcで作成したmpegtsのデータにこのdescriptorの定義がありましたが、情報がみつからない・・・ * とりあえず・・・ * type:0x05 4 AC-3と書いてあった * type:0x0A 4 00 00 00 00で埋まってた。 * の2種類だけ見つかりました。なんだろうねぇこれ・・・ * @see http://www.etherguidesystems.com/help/sdos/mpeg/semantics/mpeg-2/descriptors/Default.aspx * 情報めっけ */ private List<Descriptor> descriptors = new ArrayList<Descriptor>(); // private Descriptor esDescriptor; // 形式がわからないので、とりあえず放置 public int getSize() { return 5 + esInfoLength; } /** * 対象pidを取得 * @return */ public short getPid() { return pid; } public static PmtElementaryField makeNewField(CodecType codec) { PmtElementaryField elementField = new PmtElementaryField(); elementField.streamType = new Bit8(codec.intValue()); elementField.reserved1 = new Bit3(0x07); elementField.pid = nextTrackPid ++; elementField.reserved2 = new Bit4(0x0F); elementField.esInfoLength = 0; return elementField; } /** * 対象コーデックタイプを取得 * @return * @throws Exception */ public CodecType getCodecType() throws Exception { return CodecType.getType(streamType.get()); } public List<Bit> getBits() { List<Bit> list = new ArrayList<Bit>(); list.add(streamType); list.add(reserved1); list.add(new Bit5(pid >>> 8)); list.add(new Bit8(pid)); list.add(reserved2); list.add(new Bit4(esInfoLength >>> 8)); list.add(new Bit8(esInfoLength)); for(Descriptor descriptor : descriptors) { list.addAll(descriptor.getBits()); } return list; } /** * 保持descriptorを応答する */ public List<Descriptor> getDescriptors() { return new ArrayList<Descriptor>(descriptors); } /** * 解析しておく。 * @param ch * @throws Exception */ public void analyze(IReadChannel ch) throws Exception { streamType = new Bit8(); reserved1 = new Bit3(); Bit5 pid_1 = new Bit5(); Bit8 pid_2 = new Bit8(); reserved2 = new Bit4(); Bit4 esInfoLength_1 = new Bit4(); Bit8 esInfoLength_2 = new Bit8(); BitLoader bitLoader = new BitLoader(ch); bitLoader.load(streamType, reserved1, pid_1, pid_2, reserved2, esInfoLength_1, esInfoLength_2); pid = (short)((pid_1.get() << 8) | pid_2.get()); if(pid > nextTrackPid) { nextTrackPid = (short)(pid + 1); } esInfoLength = (short)((esInfoLength_1.get() << 8) | esInfoLength_2.get()); int size = esInfoLength; while(size > 0) { Descriptor descriptor = Descriptor.getDescriptor(ch); size -= descriptor.getDescriptorLength().get() + 2; // データ長 + データtype&length定義分 descriptors.add(descriptor); } } @Override public String toString() { StringBuilder data = new StringBuilder(); data.append(" "); data.append("pmtElementrayField:"); try { data.append(" type:").append(CodecType.getType(streamType.get())); } catch (Exception e) { } data.append(" r1:").append(reserved1); data.append(" pid:").append(Integer.toHexString(pid)); data.append(" r2:").append(reserved2); data.append(" eil").append(Integer.toHexString(esInfoLength)); for(Descriptor descriptor : descriptors) { data.append("\n"); data.append(descriptor); } return data.toString(); } }